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...
精彩评论