"强制转换"返回类型

Mat*_*ell 2 c# types

这应该是一个非常微不足道的.

C#可以返回"强制转换"类型,即以下失败的类型:

 private ICollection<string> _strings = new List<string>();
 public IEnumerable<string> Strings
 {
     get
     {
          return ((IEnumerable<string>)_strings);
     }
 }

 /* I should not know that Strings can be cast to ICollection */
 public void AddToStrings()
 {
     ICollection<string> st = ((ICollection<string>)Strings); /* I should fail */
     st.Add("MyString");
 }
Run Code Online (Sandbox Code Playgroud)

我知道我可以这样做:

 public IEnumerable<string> Strings
 {
     get
     {
          return ((IEnumerable<string>)_strings.ToArray());
     }
 }
Run Code Online (Sandbox Code Playgroud)

但这似乎是(1)不必要的,(2)仍然不会阻止他们投入ICollection,只是添加和(3)我只是对一般问题感到好奇.

澄清

有些人似乎不确定我想在这里实现什么.我试图阻止外部课程违反我提供的合同.我没有说过Strings是一个ICollection - 它恰好发生在我内部使用它 - 因此没有外部类应该能够将我返回的变量视为ICollection.我不想向它们公开修改行为,我不希望它们将我的变量视为ICollection,以防我以后改变生成IEnumerable的方式.

更一般地说,我可以将对象作为其特定类型之一的实例返回,并防止以后转换为其更常规类型之一.例如,虽然你可以产生一个新的IEnumerable,你可以返回一个IDisposable对象,它不能被转换回它的任何类型(即只有Dispose()和对象方法可调用)?

Tho*_*que 5

好的,我明白你的意思了......

 public IEnumerable<string> Strings
 {
     get
     {
          foreach (var s in _strings) yield return s;
     }
 }
Run Code Online (Sandbox Code Playgroud)

但它与拳击无关......


Ree*_*sey 5

对于这个特定的例子,托马斯为您提供了正确的答案.

话虽如此,没有"通用"方法来阻止用户尝试将类型转换为"实际"类型而不是您提供的接口.

您可以做的最接近的事情是使用程序集内部的类型,并且对调用者不可见.这将阻止用户直接使用您的类型(至少在高架信任情况下不采用反射).

但是,总的来说,我建议不要担心这一点.将您的类型转换为未记录的内部实现细节类型的任何用户只是在寻找麻烦,我不会尝试编写一种防止这种情况的方法.这样做只会让你自己受到伤害,因为你的代码不易维护.