2010-09-22 74 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