public class A { }public class B : A { }public class C : B { }
理想情况下,我希望能够将A,B或C列表传递给单个方法,如下所示:
private voID Method(List<A> foos) { /* Method Implementation */ }B toBee = new B();B nottoBee = new B();List<B> hive = new List<B> { toBee,nottoBee };// Call Method() with a inherited type. This throws a COMPILER ERROR // because although B is an A,a List<B> is NOT a List<A>.Method(hive);
我想提出一种方法来获得相同的功能,尽可能少的代码重复.
我能想到的最好的方法是创建包含各种类型列表的包装器方法,然后遍历传递的列表来调用相同的方法;最后使用多态对我有利:
private voID Method(List<A> foos) { foreach (var foo in foos) bar(foo); }private voID Method(List<B> foos) { foreach (var foo in foos) bar(foo); }private voID Method(List<C> foos) { foreach (var foo in foos) bar(foo); }// An A,B or C object can be passed to this method thanks to polymorphismprivate voID bar(A ayy) { /* Method Implementation */ }
你可以看到总线,我已经三次复制和粘贴该方法,只改变列表通用中包含的类型.我开始相信,无论何时开始复制和粘贴代码,都有更好的方法来做到这一点……但我似乎无法想出一个.
如何在没有不受欢迎的复制和粘贴的情况下完成这样的壮举?
解决方法 创建一个 generic method:private voID Method<T>(List<T> foos)
所以你可以将它用于各种List< T>.您还可以使用generic constraints缩小方法的接受参数列表,以便仅处理A子类:
private voID Method<T>(List<T> foos) where T : A
然后你确定foos的每个元素都可以用作A的实例:
private voID Method<T>(List<T> foos) where T : A{ foreach (var foo in foos) { var fooA = foo as A; // fooA != null always (if foo wasn't null already) bar(fooA); }}
正如Lucas Trzesniewski在他的回答中指出的那样,它甚至更好如果您不需要修改集合,请使用IEnumerable< T>.这是协变的,所以你不会遇到你所描述的问题.
总结以上是内存溢出为你收集整理的c# – 与列表的多态性全部内容,希望文章能够帮你解决c# – 与列表的多态性所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)