I have logic similar to the code below. It seems as though in order to check for null references like this, I have to have two separate Select statements. Could a linq ninja tell me in which way a query like this could be improved?
List<C> cList = Globals.GetReferences(irrelevantThing) // GetReferences returns List<A>, which are references to B
.Select(a => a.GetB()) // GetB returns type B, can be null
.Where(b => b != null && someOtherConditions)
.Select(c => new C(b)) // C Constructor cannot have a null parameter
.ToList();
Thank you.
EDIT: Cleaned up example code a little bit.
Well, for one thing I'd change the parameter names - after the first Select, you've got a B, so why not call it b?
List<B> bList = Globals.GetReferences(irrelevantThing)
.Select(a => a.GetB()) // GetB returns type B, can be null
.Where(b => b != null && someOtherConditions)
.Select(b => new B(b))
.ToList();
At that point, I have to wonder why you've got the second Select at all... you've already got a B, so why are you creating a new one? What does the B(B old) constructor do?
If you do need the other select though, that seems okay to me. I mean, if GetB is cheap, you could always use:
List<B> bList = Globals.GetReferences(irrelevantThing)
.Where(a => a.GetB() != null && someOtherConditions)
.Select(a => new B(a.GetB()))
.ToList();
... but I'm not sure I would, to be honest.
I find it slightly better looking with the query syntax and the let operator:
var queryB = from a in Globals.GetReferences(irrelevantThing)
let b = a.GetB()
where b != null && someOtherConditions
select new B(b);
var bList = queryB.ToList()
Depends on your preferences though...
FYI in extension method syntax, the above translates to
var queryB = Globals.GetReferences(irrelevantThing)
.Select(a => new { a, b = a.GetB() })
.Where(x => x.b != null && someOtherConditions)
.Select(x => new B(x.b))
.ToList();
UPDATE: just realized that you can also use the select into clause to translate the exact original query literally :
var queryB = from a in Globals.GetReferences(irrelevantThing)
select a.GetB() into b
where b != null && someOtherConditions
select new B(b);
still prefer let though...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With