Daniele Sartori
Daniele Sartori

Reputation: 1703

How to get specific items from List<object> when all the object are different types of EventArgs

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 EventArgsnamed 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

Answers (3)

Damien_The_Unbeliever
Damien_The_Unbeliever

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

mmathis
mmathis

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

Slappywag
Slappywag

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

Related Questions