如何使用LINQ从基类对象的集合转换为各自子类的筛选列表?

时间:2013-04-17 03:44:29

标签: c# linq lambda

我们有几种不同的数据类型,它们共享一个特定的基类。我们还有一个List<BaseClass>,它包含这些子类对象的随机集合,没有特定的顺序。

使用Linq / Lambda表达式,我们尝试提取每个单独的子类类型,按该特定子类的属性排序,然后将其存储在强类型值List<SubclassType>

这是我目前正在做的事情,但不是LINQ专家,我觉得有一种更简单的方法来实现这一目标。 (我感觉我的Where和Select在某种程度上是多余的,并导致超过集合的超过需要的传递,但我可能是错的。)

class baseItem{}

class subItemX : baseItem
{
    public int XSortValue{ get; set; }
}

class subItemY : baseItem
{
    public int YSortValue{ get; set; }
}

List<MyBaseClass> allItems = GetAllItems(); // Random collection of subclass objects.

// Is there an easier/less verbose way to achieve these two?
List<SubItemX> xItemsOnly = allItems
    .Where(baseItem => baseItem is SubItemX)
    .Select(baseItem => baseItem as SubItemX)
    .OrderBy(subItemX => subItemX.XSortValue)
    .ToList();

List<SubItemY> yItemsOnly = allItems
    .Where(baseItem => baseItem is SubItemY)
    .Select(baseItem => baseItem as SubItemY)
    .OrderBy(subItemY => subItemY.YSortValue)
    .ToList();

然而,我有一种感觉,我已经使这些变得比他们需要的复杂得多。这是最有效的方式吗?

1 个答案:

答案 0 :(得分:7)

您希望利用OfType<T>过滤混合序列并将结果提取为所需类型。

var xItemsOnly = allItems.OfType<SubItemX>().OrderBy(s => s.XSortValue).ToList();

您可能希望探索的类似方法是Cast<T>,而不是过滤和转换,只需转换(如果转换不成功则抛出)。如果知道,则使用此项。较小派生类型的序列中的所有项目实际上都是派生类型。否则,如果您的意图是过滤可能混合的序列,请使用先前显示的OfType<T>方法(这肯定是您要做的,给出您的问题)。