通过linq从多个列表中选择项目

时间:2014-10-16 19:18:47

标签: c# linq list select

我有以下问题:

class Base
{
   int val;
}
class A : Base
{
}
class B : Base
{
}

//Now I want to select from list of a and b
List<A> aList;
List<B> bList;
IEnumerable<Base> Find(int i)
{
//would need something like this
  return from a in (aList and bList) where a.val == i select a as Base;
}

最快的解决方案是什么?我应该在之后加入枚举,还是可以在linq查询中加入?

编辑:.Concat会是最快捷的方式吗?

3 个答案:

答案 0 :(得分:3)

怎么样:

return lista.Cast<Base>().Concat(listb).Where( x => x.val == i);

Cast<Base>必须有一个同类型列表,Concat与Union相同,但不会产生重复消除的开销。

答案 1 :(得分:0)

首先,使用.OfType方法来强制转换所有内容并允许每个集合使用相同的类型。这只会对已经具有所需类型的对象执行显式强制转换,并且只返回所需类型的对象 - 我觉得它非常适合像这样的向上转换。

然而,第二个集合不需要强制转换 - 因为IEnumerable<out T>定义使用out,您可以允许多态性正确地对第二个集合起作用。有关此行为的详细信息,请参阅Covariance and Contravariance

如果您想要返回所有内容而不管比较,请使用.Concat

aList.OfType<Base>()
.Contat(bList)

如果您希望每件商品只返回一次,请使用.Union

aList.OfType<Base>()
.Union(bList)

我个人建议Concat超过Union,因为它只返回每个元素,而Union会检查重复项的开销,这个任务更适合.Distnict Method

答案 2 :(得分:-1)

您可以使用Union

return from a in (aList.Union<Base>(bList)) where a.val == i select a as Base;
  

使用默认的相等比较器生成两个序列的集合。

http://msdn.microsoft.com/en-us/library/vstudio/bb341731(v=vs.100).aspx

<强>更新

Union将返回两个列表中的所有唯一元素(即,如果两个列表中的相同元素,则只返回其中一个

  

Concat(IEnumerable,IEnumerable)方法与Union方法不同,因为Concat(IEnumerable,IEnumerable)方法返回输入序列中的所有原始元素。 Union方法仅返回唯一元素。

http://msdn.microsoft.com/en-us/library/vstudio/bb302894(v=vs.100).aspx

如果不需要此行为,请使用Concat

return from a in (aList.Concat<Base>(bList)) where a.val == i select a as Base;