2010-09-22 63 views
6

我有下面的语句,它总是返回null:为什么Null无效的LINQ投影?

var addins = allocations.SelectMany(
     set => set.locations.Any(q => q.IsMatch(level, count)) 
     ? (List<string>)set.addins : null 
    ); 

我改变了它略显不足,现在它工作正常:

var addins = allocations.SelectMany(
     set => set.locations.Any(q => q.IsMatch(level, count)) 
     ? set.addins : new List<string>() 
    ); 

我的主要问题:不为空,为什么可以作为在LINQ的这个上下文中来自三元运算符的返回类型?

第二个问题:是否有一种更聪明的方式来制定上述查询(特别是如果它消除了“新List()”)?

回答

11

Enumerable.SelectMany将尝试枚举通过你的拉姆达返回的序列,它抛出一个NullReferenceException尝试在空调用的GetEnumerator()。您需要提供一个实际的空序列。而不是创建一个新的列表,你可以使用Enumerable.Empty

var addins = allocations.SelectMany(
    set => set.locations.Any(q => q.IsMatch(level, count)) 
    ? (List<string>)set.addins : Enumerable.Empty<string>() 
    ); 

我怀疑你真正想要的是只是调用之前在哪里来的SelectMany筛选出集你不想要的:

var addins = allocations 
    .Where(set => set.locations.Any(q => q.IsMatch(level, count))) 
    .SelectMany(set => (List<string>)set.addins); 

或者,在查询语法中:

var addins = 
    from set in allocations 
    where set.locations.Any(q => q.IsMatch(level, count)) 
    from addin in (List<string>)set.addins 
    select addin; 
+1

优秀的答案和见解。顺便说一句,“set.addins”在你的其他例子中不是必须的,因为三元运算符没有涉及。 – 2010-09-22 03:27:23

1

作出这样的:

(List<string>)set.addins : (List<string>)null

+0

我已经尝试过了。它没有改变任何东西。 :( – 2010-09-22 03:27:04