泛型和选角

本文关键字:泛型 | 更新日期: 2023-09-27 17:58:53

class B : A {}
class Sub<T> where T:A
{
//...
}

我想将子实例存储在集合中。

var c = new List<Sub<A>>();
c.Add(new Sub<B>()); //doesn't work

然而,为了使它真正工作,我必须声明一个接口并存储该接口的实例。

interface IBase
{
    void DoStuff(A a);
}
var c = new List<IBase>();
c.Add(new Sub<B>()); //works

有更优雅的方法吗?

泛型和选角

否。具有不同类型参数的泛型类型的实例化是完全不相关的。将它们放在同一个列表中的唯一方法是让列表使用一个通用的非泛型基类或接口,就像您在这里所做的那样。

您可以通过使用协变通用接口来实现您想要的近似值:

class A { }
class B : A { }
interface ISub<out T> where T : A
{
    // Members go here
}
class Sub<T> : ISub<T> where T : A
{
    // Members go here.
}

可按如下方式使用:

List<ISub<A>> list = new List<ISub<A>>();
list.Add(new Sub<B>());

您需要一个接口,因为只有接口才能具有协变或逆变类型参数。

这取决于您如何使用它,但也许您可以为Sub:使用协变接口

interface ISub<out T> where T:A
{
}

然后ISub<B>可以隐式转换(通过引用转换(为ISub<A>