C#和使用泛型的多种类型的继承链

时间:2016-06-07 11:14:51

标签: c# generics inheritance clr

我有这个设置,它没有像我预期的那样工作。在我看来,基类中的泛型T与其子类中的泛型T不同。

namespace StackOverflowQuestion
{
    public class Poco1
    {
        public string Data { get; set; }
    }

    public class Poco2 : Poco1
    {
        public string ExtraData { get; set; }
    }

    public class Poco3 : Poco2
    {
        public string EvenMoreData { get; set; }
    }


    public class Base<T> where T: Poco1
    {
        public virtual void Method(T parameter)
        {
            // Do something even more general with Data...
            parameter.Data = "Test";
        }
    }

    public class FirstLevel<T> : Base<Poco2> where T:Poco2
    {
        public override void Method(Poco2 parameter)
        {
            // Do something general with ExtraData...
            base.Method(parameter);
        }
    }

    public class SecondLevel<T> : FirstLevel<Poco3> where T: Poco3
    {
        public override void Method(Poco2 parameter)  // <-- Why not Poco3?
        {
            // Do something with EvenMoreData...
            base.Method(parameter);
        }
    }
}

我实际期望的是Method类型中的SecondLevel<T>覆盖应该说Poco3而不是Poco2。特别是因为我对T的约束是Poco3类型。

是否有可能以另一种方式实现这一目标?在我看来,通用T不能按照我想要的方式&#34;覆盖&#34; 。我怀疑Base<T>中的T与FirstLevel<T>中的T不同,而FirstLevel<T>中的T与SecondLevel<T>中的T不同?

如果SecondLevel<T>继承自Base<T>,那么我会在Poco3覆盖中获得Method,但不会从FirstLevel<T>继承。

我可以忍受这个问题,但是我需要在Level-type子类(从2级及以上)中转换poco参数类型。在我看来,只要我指定约束,这应该是不必要的。但是,当然,我现在还没有看到这种行为的充分理由。

1 个答案:

答案 0 :(得分:2)

您可以改为使用T类型参数,而不是在每个重写方法签名中指定POCO类型。

T已被约束到您想要的POCO类型,因此它应该完全符合您的要求。

哦,我也会对您传递给基类的类型做同样的事情。

e.g。

public class FirstLevel<T> : Base<T> where T:Poco2
{
    public override void Method(T parameter)
    {
        // Do something general with ExtraData...
        base.Method(parameter);
    }
}

public class SecondLevel<T> : FirstLevel<T> where T: Poco3
{
    public override void Method(T parameter)
    {
        // Do something with EvenMoreData...
        base.Method(parameter);
    }
}