加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 与列表的多态性

发布时间:2020-12-15 19:47:28 所属栏目:百科 来源:网络整理
导读:我有一个对象的继承结构,有点像下面这样: public class A { }public class B : A { }public class C : B { } 理想情况下,我希望能够将A,B或C列表传递给单个方法,如下所示: private void Method(ListA foos) { /* Method Implementation */ }B toBee = new
我有一个对象的继承结构,有点像下面这样:

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 polymorphism
private 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>.这是协变的,所以你不会遇到你所描述的问题.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读