为什么泛型方法无法将具体(派生的)类转换为其父类

时间:2018-12-20 22:12:21

标签: c# generics inheritance

我遇到一种情况,我想Deal class意识到DealDetail type,反之亦然,我想DealDetail意识到Deal type。将来我想拥有DealDealDetails

的许多后代

我尝试使用泛型来实现它,但是它不想编译。 编译器给出错误:无法将类型'Program.ConcreateDeal'隐式转换为'TDeal'

public static void Main()
{
    Console.WriteLine("Hello World");

    var deal = GetDeal<ConcreateDeal,ConcreateDealInfo>();
}

public static TDeal GetDeal<TDeal, TDealInfo>()
    where TDeal : DealBase<TDeal, TDealInfo>
    where TDealInfo : DealInfoBase<TDeal, TDealInfo>
{
        return new ConcreateDeal();
}

public class DealBase<TDeal, TDealInfo> 
    where TDeal : DealBase<TDeal, TDealInfo>
    where TDealInfo : DealInfoBase<TDeal, TDealInfo>
{
    public TDealInfo DealInfo {get; set;} 
}

public class ConcreateDeal : DealBase<ConcreateDeal, ConcreateDealInfo> {}

public class DealInfoBase<TDeal, TDealInfo>
    where TDeal : DealBase<TDeal, TDealInfo>
    where TDealInfo : DealInfoBase<TDeal, TDealInfo>

{
    public TDeal Deal {get; set;} 
}

public class ConcreateDealInfo : DealInfoBase<ConcreateDeal, ConcreateDealInfo> { }     

我希望在方法GetDeal<ConcreateDeal,ConcreateDealInfo>()中,类型ConcreateDeal将通过继承隐式转换为基础Deal type,但事实并非如此。我在哪里错了?

dotnetfiddle:https://dotnetfiddle.net/sjtxTC

1 个答案:

答案 0 :(得分:3)

编译器错误在这里:

public static TDeal GetDeal<TDeal, TDealInfo>()
    where TDeal : DealBase<TDeal, TDealInfo>
    where TDealInfo : DealInfoBase<TDeal, TDealInfo>
{
    return new ConcreateDeal(); // <== compiler error
}

您正在提供通用参数,这些参数指定返回类型必须为DealBase<TDeal, TDealInfo>。您可以编写从DealBaseDealInfoBase继承的任意数量的类,然后可以使用与ConcreteDeal不对应的通用参数来调用该方法。

由于泛型参数的数量众多,因此很难看到。这是一个简单的版本,带有较少的通用参数来说明。这很简单,但是是同一回事。

public class Dog : Animal { }
public class Cat : Animal { }

public class Animal
{
    public static TAnimal GetAnimal<TAnimal>()
    {
        return new Dog();
    }
}

由于完全相同的原因,它将无法编译。

泛型参数表示该方法将返回TAnimal。因此,如果您致电

var cat = Animal.GetAnimal<Cat>();

返回类型 必须为Cat。但是,该方法将按原样返回Dog。这没有任何意义,因此编译器会阻止它。