I came across this article a while ago which was very interesting so it got my attention.
Basically, LINQ may automatically optimize multiple methods by combining them or change the execution order. If you have OrderBy(…).First(…) or OrderBy(…).FirstOrDefault(…), it might not execute as you would expect. My first thought is it the First() or FirstOrDefault() predicate would be invoked up to N times. However, it actually invoke the predicate exactly N times. This optimisation was introduced in .NET Core 1.0
This is a similar example to the one from the article.
That output shows that it executes the FirstOrDefault predicate on every item to find all the things that match the clause first and then ordering them to find out which should be first. This optimisation actually makes sense as sorting is not cheap and less efficient than comparing. This also means that it might only need to sort fewer than N items, which could have a massive performance gain in a large list.
Interestingly, this optimisation does not exist for Where clause.
I think this might be because it does not know what the Where is going to be used for.
Even though this is a very useful optimisation in my opinion, it is being removed in the upcoming .NET 5.0 due to
Community feedback that the cost of potentially invoking the predicate more times outweighed the benefit of a lower complexity operation overall.
You can see the GitHub issue here.
I don’t agree with that reason to remove this optimisation. When you use First() or FirstOrDefault(), you should be prepared that it could invoke the predicate up to N times. Hence you should not have anything too expensive or have side effects in the predicate in the first place.