Reputation: 1155
I have the following issue:
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;
}
What would be the fastest solution for this ? Should I join the enumerations afterwards or is that possible within the linq query ?
edit: Would .Concat be the quickest way ?
Upvotes: 1
Views: 1397
Reputation: 150108
You can use Union
return from a in (aList.Union<Base>(bList)) where a.val == i select a as Base;
Produces the set union of two sequences by using the default equality comparer.
http://msdn.microsoft.com/en-us/library/vstudio/bb341731(v=vs.100).aspx
UPDATE
Union will return all of the unique elements in both lists (that is, if the same element were in both lists, only one of them would be returned
The Concat(IEnumerable, IEnumerable) method differs from the Union method because the Concat(IEnumerable, IEnumerable) method returns all the original elements in the input sequences. The Union method returns only unique elements.
http://msdn.microsoft.com/en-us/library/vstudio/bb302894(v=vs.100).aspx
If this behavior is not desired, use Concat
return from a in (aList.Concat<Base>(bList)) where a.val == i select a as Base;
Upvotes: -1
Reputation: 10591
How about:
return lista.Cast<Base>().Concat(listb).Where( x => x.val == i);
Cast<Base>
is necessary to have a list of homogenous types, and Concat
is the same as Union but will not incur the overhead of duplicate elimination.
Upvotes: 3
Reputation: 10708
First off, use a .OfType method to cast everything and allow each collection to be the same type. This will only perform an explicit cast on objects already of the desired type, and return only objects of the desired type - I find it perfect for upcasting situations like this.
The second collection does not need to be cast, however - because of the definition of IEnumerable<out T>
uses out
you can allow polymorphism to act on the second collection properly. See Covariance and Contravariance for more info on this behaviour.
If you want everything returned regardless of comparison, use .Concat
aList.OfType<Base>()
.Contat(bList)
If you want each item returned only once, use .Union
aList.OfType<Base>()
.Union(bList)
I Personally recommend Concat
over Union
, since it simply returns every element, whereas Union
does the overhead of checking for duplicates, a task better suited to the .Distnict
Method
Upvotes: 0