将MyClass <tdescendent>转换为MyClass <tancestor>

时间:2016-05-17 21:01:15

标签: c# generics

如果我有根界面

public interface IEntity {}

派生的接口和类:

public interface IFruit : IEntity {}
public class Apple : IFruit {}
public class Orange: IFruit {}

并且,无关紧要,但也许是其他没有实现IFruit的人:

public class Computer : IEntity {}

使用所有这一切的通用类:

public class PurchasedItem<T> where T : IFruit 
{
    public int Qty{get;set;}
    public T Item{get;set;}
}

如何声明包含PurchasedItem<IFruit>的列表并使用它? 如果我这样做:

var list = new List<PurchasedItem<IFruit>>();
list.Add(new PurchasedItem<Apple>());

...然后我收到错误

Cannot convert from PurchasedItem<Apple> to PurchasedItem<IFruit>

2 个答案:

答案 0 :(得分:4)

如果您创建并使用PurchaseItem<T>

的界面,则可以使用协方差
public interface IEntity
{
    int Id { get; set; }
}

public interface IFruit : IEntity
{
}

public class Apple : IFruit
{
    public int Id { get; set; }
}

public interface IPurchaseItem<out T> where T : IFruit
{
    int Qty { get; set; }
    T Item { get; } // can't have setter here
}

public class PurchaseItem<T> : IPurchaseItem<T>
    where T : IFruit
{
    public int Qty { get; set; }
    public T Item { get; set; } // setter here no problem
}


class Program
{

    static void Main()
    {
        var applePurchaseItem = new PurchaseItem<Apple>();

        var fruitPurchaseItems = new List<IPurchaseItem<IFruit>>();

        fruitPurchaseItems.Add( applePurchaseItem );
    }
}

答案 1 :(得分:2)

这一切都归结为类树的设计。例如,请参阅以下代码:

public interface IEntity {}

public interface IFruit : IEntity {}

public class PurchasedItem
{
    public int Qty { get; set; }
}

public class Apple : PurchasedItem, IFruit {}
public class Orange: PurchasedItem, IFruit {}

var list = new List<PurchasedItem>();