Reputation: 1703
I have a list of object called eventQueue
in which i've stored all the event produced by a task executed in background. Now, i need to handle this list extracting specific event from it. I would like to use LINQ mostly for code readability (i wouldn't like to write multiple foreach), my problem is that i don't exactly know how to proceed. Suppose that i have multiple instance of a custom EventArgs
named FirstEventArgs
, and i want to extract a specific one from the list, doing a foreach i would write
foreach(object o in eventQueue)
{
if( o is FirstEventArgs)
{
FirstEventArgs ev = o as FirstEventArgs ;
if( ev.MyProperty == desiredValue)
{
// you got it
}
}
}
currently i was able to write the following in LINQ
FirstEventArgs ev = eventQueue.Where(x => x.GetType() == typeof(FirstEventArgs )).SingleOrDefault() as FirstEventArgs;
my problem is. How do i modify the previous to add the condition ev.MyProperty = desiredValue
in the Where if x is of type object?
Upvotes: 1
Views: 53
Reputation: 239764
OfType
lets you do a type test and throws in the cast for free:
FirstEventArgs ev = eventQueue
.OfType<FirstEventArgs>()
.SingleOrDefault(fea=>fea.MyProperty==desiredValue);
(I also moved the remaining filtering into the SingleOrDefault
call because, why not?)
Yes, the other answers also work, but there's still a bit too much "mechanism" for my tastes, versus just declaring what we want.
Upvotes: 2
Reputation: 1610
You can use pattern matching in your LINQ query to cast the object to your type:
FirstEventArgs ev = eventQueue.Where(x => x is FirstEventArgs fea && fea.MyProperty == desiredValue)
.SingleOrDefault() as FirstEventArgs;
Thanks to @Slappywag for checking that it works!
Upvotes: 3
Reputation: 1223
You can use an &&
operator and then cast to the desired type. The second half of the AND statement will only be evaluated if the first half is true, so you won't get any errors from the cast. This is known as short circuit evaluation and according to this answer (Is relying on && short-circuiting safe in .NET?) can be relied upon in C#.
FirstEventArgs ev = eventQueue.Where(x => x.GetType() == typeof(FirstEventArgs)
&& ((FirstEventArgs)x).MyProperty == desiredValue)
.SingleOrDefault() as FirstEventArgs;
Upvotes: 2