Understanding LINQ

return stats.FirstOrDefault(element => element.StatType == stat);

You can pass the condition straight to FirstOrDefault method, no need for Where with it,

why do you want to use ‘Where’ when you’re just aiming for the first value of a list? I use the ‘Where’ a lot, typically when I’m searching for values on a list that meet very specific conditions

One such example is in my own self-developed AI Intelligence system for my enemies. I use the ‘Where’ when I only want enemies who are not fighting someone to aim for some unoccupied enemy for example

‘FirstOrDefault’ can be used as a hot shortcut for when you’re sure that something static permanently holds the first position. I use that in my game’s banking system, or interaction system

For example, if I’m near an anvil, and I’m closer to it than I am to a crafting table, hit the “Interact” button in my game, I’ll get the Smithing UI instead of the Crafting UI. That’s one area where I find it beneficial

Another example is in my banking system. I only have 2 inventories, and my bank is on top of my inventory in the hierarchy. If I want to open the bank, I just use ‘FirstOrDefault()’, because it’s never going to change positions in the hierarchy for any weird reason

Apologies for the confusion. In the context of the lesson, the instructor used this multiple times: array.Where(x => x == y).FirstOrDefault() , I was just pointing out for this case the Where method is not needed because FirstOrDefault is able to accept the condition and return the first match.

I think it compiles to the same IL, so functionally this code should be no different just less keystrokes.

I think what your function is trying to do is get all values on the list where ‘x == y’, and get the first one, for whatever reason you’re doing.

Basically, they don’t want all the values. They just want the first one

I can see this being helpful in multiple areas, especially if you have more than one potential ‘x==y’ on your list, but I’m not sure which course you’re doing or where you’re stuck. Provide us more details, and we can try and help you out if you’re stuck

OP is not stuck. They’re saying that instead of writing

return stats.Where(element => element.StatType == stat).FirstOrDefault();

you could have written

return stats.FirstOrDefault(element => element.StatType == stat);

Because FirstOrDefault provides an overload that accepts a filter.

If you are using a list you could do

return stats.Find(element => element.StatType == stat);

which is native to a list and skips Linq altogether. For arrays it would be

return Array.Find(stats, element => element.StatType == stat);
2 Likes

Yes, when FirstOrDefault is presented with a Lambda expression, a .Where is effectively inserted into the code behind the scenes.

Personally, prefer the .Where construction because it looks closer to an SQL query

SELECT TOP 1* FROM STATS WHERE STATTYPE = STAT

Linq was originally designed to be a sort of drop in replacement for SQL (in fact, it can take a modified form of SQL syntax, but I’ve never made it work right). As the years have gone by, Linq has gotten more powerful and can plow through just about any data structure and make some data tricks SQL has trouble with (at least it does for me).

While this is true for things like Where(...).Select(...), the code created by the compiler in this case is not great.

In the case of x.FirstOrDefault(...) the generated code becomes something like

Enemrable.FirstOrDefault(...);

while x.Where(...).FirstOrDefault() becomes

Enumerable.FirstOrDefault(Enumerable.Where(...));

It feels like an oversight from the .NET guys because they certainly optimised Where(...).Select(...) (and other common patterns) to compact into single instructions, but I looked at the source (at source.dot.net) as well as the compiled bits (see the gist) and there’s no optimisation for Where(...).FirstOrDefault(...)

ahh, talk about me bonding two good friends of mine just by tagging them :stuck_out_tongue:

(I’m lost now as we speak)

Privacy & Terms