2013-04-26 122 views
2
var person = People.SingleOrDefault(p => p.Name == parameter); 
SelectedPerson = person ?? DefaultPerson 

這是寫在一個語句嗎? Measing可以提供SingleOrDefault返回的默認元素嗎?LINQ語句優化

我正在尋找這樣的成才(第二個參數是默認元素我公司提供)。

var person = People.SingleOrDefault(p => p.Name == parameter, DefaultPerson); 

該解決方案還應該適用於值類型(整數,雙精度,枚舉,結構等)。

+3

怎麼樣'SelectedPerson = People.SingleOrDefault(P => p.Name ==參數)?? DefaultPerson'?它應該工作。 – J0HN 2013-04-26 18:02:08

+0

如何區分'ints'的「有效」0或「默認」0? – 2013-04-26 18:12:17

回答

7

您可以使用DefaultIfEmpty():

var person = People.Where(p => p.Name == parameter).DefaultIfEmpty(DefaultPerson).Single(); 
+2

'DefaultIfEmpty'仍然返回'IEnumerable',所以需要另一個'First()'。但是,是的,這就是我一直在尋找的! Thx – 2013-04-26 18:12:35

+0

@WolfgangZiegler:需要另一個_Single()_來提供相同的行爲。 – 2013-04-26 18:14:04

+0

你是對的,最後應該有single()。 – 2013-04-26 18:17:48

2

這是一個有點明顯,但這樣做對你的工作?

var person = People.SingleOrDefault(p => p.Name == parameter) ?? DefaultPerson; 
+0

我正在尋找更通用的解決方案,它也適用於值類型(int,double,structs,...)。對不起,這個壞例子... – 2013-04-26 18:04:25

4

您可以定義一個擴展:

public static T SingleOrDefault<T> 
    (this IEnumerable<T> list, T defaultValue) 
    where T : class 
{ 
    return list.SingleOrDefault() ?? defaultValue; 
} 

,然後用調用它:

var person = People.SingleOrDefault(p => p.Name == parameter, DefaultPerson); 
-1

您可以創建一個擴展方法,它給你一個實例如果什麼都不會被發現:

public static class PersonExtensionMethod 
{ 
    public static T SingleOrInstance<T>(this IEnumerable<T> source, Func<T, bool> precate) 
    { 
     var person = source.SingleOrDefault(precate); 

     if (person == null) 
      return (T)Activator.CreateInstance(typeof(T)); 

     return person; 
    } 
} 

,並調用它像這樣:

List<Person> persons = new List<Person> { new Person(), new Person(), new Person() }; 

var foundPerson = persons.SingleOrInstance<Person>(p => p.Name == "bla");