In most situations, you should be able to filter on the source enumerable before mapping making the whole thing more efficient.
Additionally, that `.Cast<TR>(..)` at the end should have been a dead giveaway that you are going down the wrong path here. You are incurring even more CPU and Memory costs as the `.Cast<TR>(..)` call will now iterate through all the items needlessly.[1]
Also, the design of this this method doesn't seem to make much difference to me anyways:
``` var strs = source.SelectNotNull(it => it); ```
vs
``` var strs = source.Where(it => it != null); ```
A lot of other LINQ extension methods allow you to pass in a predicate expression that will be executed on the source enumerable:
``` var str = source.First(it => it != null); ```
[1] https://source.dot.net/#System.Linq/System/Linq/Cast.cs,152b...
``` var strs = source.SelectNotNull(it => it); ```
vs
``` var strs = source.Where(it => it != null); ```
Wouldn't the first be IEnumerable<TR> and the second be IEnumerable<TR?>
I imagine that's the main driver for creating SelectNotNull, so that you get the nonnullable type out of the Linq query
Sure. And now we are fighting the compiler and in the process writing less efficient code.
The compiler gives us a way to deal with this situation. It is all about being absolutely clear with intentions. Yes, Where(..) in my example would return IEnumerable<TR?> but then in subsequent code I can tell the compiler that I know for a fact that TR? is actually TR by using the null forgiving operator (!).