Eri*_*tas 4 c# collections types casting
假设我有一个期望基类型的泛型集合参数的方法,请参阅下面的Test.MethodA(IEnumerable(BaseClass)listA).为什么我传递代码不会构建的派生类型的集合?难道DerivedClass的所有实例都不是BaseClass吗?
我本来可以创建一个新的List(BaseClass)并将其传递给MethodA(IEnumerable(BaseClass)listA).但我认为C#足够聪明,知道DerivedClass的集合具有与BaseClass集合相同的所有属性.
使用List.Cast(T)()方法,因为我已经展示了解决此问题的最佳方法?
abstract class BaseClass
{
public int SomeField;
public abstract string SomeAbstractField
{
get;
}
}
class DerivedClass:BaseClass
{
public override string SomeAbstractField
{
get { return "foo"; }
}
}
class TestClass
{
public void MethodA(IEnumerable<BaseClass> listA)
{
}
public void MethodB()
{
List<DerivedClass> listB = new List<DerivedClass>();
//Error 16 The best overloaded method match for
//TestClass.MethodA(List<BaseClass>)'
//has some invalid arguments
this.MethodA(listB);
//this works
this.MethodA(listB.Cast<BaseClass>());
}
}
Run Code Online (Sandbox Code Playgroud)
Jon*_*eet 10
Cast<>()
是目前解决问题的最佳方法.您的原始版本在C#4.0/.NET 4.0中可以正常工作,但IEnumerable<T>
协变性在哪里T
.
(我刚刚验证它在.NET 4.0 beta 1下编译.)
在.NET 4.0和C#4问世之前,泛型是不变的 - IEnumerable<object>
并且IEnumerable<string>
实际上是无关的接口.即使在.NET 4.0中,您也无法使用List<T>
参数类型执行此操作- 仅接口和委托将是变体,即使这样,仅当type参数仅在适当的位置使用时(协方差的输出位置,输入)逆变的立场).
要了解有关C#4差异的更多信息,请阅读Eric Lippert 关于它的精彩系列博客文章.
归档时间: |
|
查看次数: |
4426 次 |
最近记录: |