将多态列表组合到一个列表中并获取派生类型

时间:2012-02-21 20:55:29

标签: c# .net generics inheritance polymorphism

我不知道我是否以正确的方式提出这个问题,但这就是我想要做的事情:

模型

public abstract class IncomingOrderBase
{
    public string Summary { get; set; }
}

public class IncomingProductOrder : IncomingOrderBase
{
    public Product Product { get; set; }
}
public class IncomingServiceOrder : IncomingOrderBase
{
    public Service Service { get; set; }
}

public class Sale
{
    public ICollection<IncomingProductOrder> ProductOrders { get; set; }
    public ICollection<IncomingServiceOrder> ServiceOrders { get; set; }

    public List<IncomingOrderBase> GetAllOrders()
    {
        var orders = this.ProductOrders +++PLUS+++ this.ServicesOrders;
        return orders.ToList();
    }
}

用法

foreach(var order in sale.GetAllOrders())
{
    Console.WriteLine(order.GetType().Name);
    //output = "ProductOrder" or "ServiceOrder" not "IncomingOrderBase"
}

如何将两个(或更多)列表编译成一个列表,然后从结果列表中获取原始(派生)类型?我认为我使用Concat()进行了工作,但我非常感谢专家的例子。

2 个答案:

答案 0 :(得分:8)

是的,Concat是你想要的:

public List<IncomingOrderBase> GetAllOrders()
{
    return ProductOrders.Concat<IncomingOrderBase>(ServicesOrders).ToList();
}

请注意,这仅适用于.NET 4,它具有IEnumerable<T>的通用协方差。如果您使用的是.NET 3.5,则需要

public List<IncomingOrderBase> GetAllOrders()
{
    return ProductOrders.Cast<IncomingOrderBase>()
                        .Concat(ServicesOrders.Cast<IncomingOrderBase>())
                        .ToList();
}

答案 1 :(得分:1)

除了建议的解决方案之外,你可以考虑这个,这是一个更清晰的代码:

var result = new List<IncomingOrderBase>(ProductOrders);
result.AddRange(ServiceOrders);
return result;