如何使用泛型类型的子类初始化泛型属性?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用泛型类型的子类初始化泛型属性?相关的知识,希望对你有一定的参考价值。

我想用其中一个子类填充泛型属性。但我得到这个错误:

无法将类型'Child1'隐式转换为'T'

我该怎么做?

例如:

考虑这些父类和子类:

public abstract class Parent
{
    public int P1 { get; set; }

    public abstract int DoSomething();
}
public class Child1 : Parent
{
    public override int DoSomething() { return P1 * 2; }
}
public class Child2 : Parent
{
    public override int DoSomething() { return P1 * 3; }
}

并且还要考虑此示例通用类:

public class Sample<T> where T: Parent
{
    T ChildObject { get; set; }

    public int Test()
    {
        ChildObject = new Child1 { P1 = 2 }; // Error: Cannot implicitly convert type 'Child1' to 'T'

        return ChildObject.DoSomething();
    }
}

更多解释:

我的错误是我试图在泛型类中初始化子类。根据接受的答案,我应该添加新约束并执行ChildObject = new T { P1 = 2 };然后使用ChildObject.DoSomething();


解:

public class Sample<T> where T: Parent, new()
{
    T ChildObject { get; set; }

    public int Test()
    {
        ChildObject = new T { P1 = 2 }; // Fixed :)

        return ChildObject.DoSomething();
    }
}
答案

将您的Sample课程更改为:

public class Sample<T> where T : Parent, new()
{
    T ChildObject { set; get; }
    public Sample()
    {
        ChildObject = new T(); 
    }
}

您现在可以创建一个实例:

var sample = new Sample<Child2>();

为了实现这一点,Child1Child2需要一个公共的无参数构造函数。这是记录here

另一答案

这是一个更具说明性的例子:

class Tiger : Mammal {}
class Zebra : Mammal {}

public class Sample<TAnimal> where TAnimal: Mammal
{
    TAnimal ChildObject { set; get; }
    void Test()
    {
        ChildObject = new Tiger(); // Error: Cannot implicitly convert type 'Tiger' to 'TAnimal'
    }
}

假设我们将Zebra用于TAnimal。它会给我们:

public class Sample<Zebra> where Zebra: Mammal
{
    Zebra ChildObject { set; get; }
    void Test()
    {
        ChildObject = new Tiger(); // Bang!
    }
}

ZebraTiger都是哺乳动物,但这并不意味着斑马是老虎因此错误。

以上是关于如何使用泛型类型的子类初始化泛型属性?的主要内容,如果未能解决你的问题,请参考以下文章

Kotlin泛型 ③ ( 泛型 out 协变 | 泛型 in 逆变 | 泛型 invariant 不变 | 泛型逆变协变代码示例 | 使用 reified 关键字检查泛型参数类型 )

如何子类化字典以支持泛型类型提示?

关于泛型

如何从父类和子类的相同方法返回泛型类型

泛型知识

关于泛型的知识