gpt4 book ai didi

c# - 列表的多态性

转载 作者:太空狗 更新时间:2023-10-29 23:58:05 26 4
gpt4 key购买 nike

我有一个对象的继承结构,有点像下面这样:

public class A { }
public class B : A { }
public class C : B { }

理想情况下,我希望能够将 ABCList 传递给像这样的单一方法:

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 polymorphism
private void Bar(A ayy) { /* Method Implementation */ }

如您所见,Bus 确实复制并粘贴了该方法三次,仅更改了列表泛型中包含的类型。我开始相信,无论何时开始复制和粘贴代码,都有更好的方法...但我似乎想不出一个。

如果没有不受欢迎的复制和粘贴,我如何才能完成这样的壮举?

最佳答案

创建一个 generic method :

private void Method<T>(List<T> foos) 

因此您将能够将它用于各种 List<T> .您还可以缩小该方法接受的参数列表以仅处理 A子类,使用 generic constraints :

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# - 列表的多态性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31525118/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com