将对象的通用集合传递给需要基类型集合的方法
假设我有一个期望基类型的generics集合参数的方法,请参阅下面的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 listA) { } public void MethodB() { List listB = new List(); //Error 16 The best overloaded method match for //TestClass.MethodA(List)' //has some invalid arguments this.MethodA(listB); //this works this.MethodA(listB.Cast()); } }
Cast<>()
是目前解决它的最佳方法。 您的原始版本在C#4.0 / .NET 4.0中可以正常工作,其中IEnumerable
在T
是协变的。
(我刚刚validation它在.NET 4.0 beta 1下编译。)
在.NET 4.0和C#4出现之前,generics是不变的 – IEnumerable
和IEnumerable
实际上是无关的接口。 即使在.NET 4.0中,您也无法使用List
作为参数类型 – 只有接口和委托才是变体,即使这样,只有当type参数仅用于适当的位置时(输出位置)对于协方差,输入逆变的位置)。
要了解有关C#4差异的更多信息,请阅读Eric Lippert关于它的一系列优秀博客文章 。
在一般情况下(即对于可修改的集合),并非“DerivedClass的集合具有与BaseClass集合相同的所有属性”的情况:进入Fruit的集合,您可以插入Banana,Apple和Pear – – 在Orange的集合中,你不能,所以,你看,它没有相同的属性(在修改中)。
IEnumerable是一个不同的情况,因为它不可修改,因为@Jon说这个特殊情况已经在4.0中删除了这个过度的限制。
上述就是C#学习教程:将对象的通用集合传递给需要基类型集合的方法分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/985610.html