2013-04-03 32 views
15

我如何整合.DefaultIfEmpty()擴展方法,所以我不使用使用.DefaultIfEmpty()代替.FirstOrDefault()?的String.Empty;

.FirstOrDefault() ?? String.Empty; 

代碼:

(from role in roleList 
let roleArray = role.RoleId.Split(new char[] { WorkflowConstants.WorkflowRoleDelimiter }) 
where roleArray.Length.Equals(_SplittedRoleIdArrayLength) && 
     HasAccessToCurrentUnit(roleArray[_UnitIndexInRoleId]) 
select roleArray[_LevelIndexInRoleId]).FirstOrDefault() ?? String.Empty; 
+2

個人而言,我不會。 'DefaultIfEmpty'對枚舉值感興趣,而不是標量值。創建您自己的擴展方法,可能命名爲'FirstOrDefault',並將'T'參數指定爲默認值。 –

回答

12

你可以使用:

var query = ...; 

return query.DefaultIfEmpty(string.Empty).First(); 

但這並不降低IMO的複雜性。

+0

是的,減少複雜性是我的目標之一。你有什麼其他建議? – Elisabeth

+1

嗨,2k先生。現在你實際上是14k! –

+0

我切換到您的解決方案。 – Elisabeth

7

如果您有興趣擴展方法,那麼你可以使用這樣的事情:

public static class Helpers 
{ 
    public static string FirstOrEmpty(this IEnumerable<string> source) 
    { 
     return source.FirstOrDefault() ?? string.Empty; 
    } 
} 

編輯

這種方法不是通用的,因爲那時我們不得不使用default(T)和它會給我們null而不是string.Empty

+1

也許然後'T FirstOrEmpty(這個IEnumerable 源)' –

+1

@Ilya Ivanov,如果它是通用的,那麼它的默認值仍然是空字符串。 –

+1

但是'T FirstOrDefault(這個IEnumerable 源碼,T默認)'是可能的。再次,'.FirstOrDefault(string.Empty)'與'.FirstOrDefault()? string.Empty'並沒有真正做出那麼大的區別。 – hvd

1

的代碼:

var query=(
    from role in roleList 
    let delimiter=WorkflowConstants.WorkflowRoleDelimiter 
    let roleArray=role.RoleId.Split(new char[] { delimiter }) 
    where roleArray.Length.Equals(_SplittedRoleIdArrayLength) 
    where HasAccessToCurrentUnit(roleArray[_UnitIndexInRoleId]) 
    select roleArray[_LevelIndexInRoleId] 
    ).DefaultIfEmpty("").FirstOrDefault(); 

有關的DefaultIfEmptyFirstOrDefault語義的嫌疑,下面是從庫反編譯的代碼:

  • 代碼

    public static IEnumerable<TSource> DefaultIfEmpty<TSource>(this IEnumerable<TSource> source) 
    { 
        return source.DefaultIfEmpty<TSource>(default(TSource)); 
    } 
    
    public static IEnumerable<TSource> DefaultIfEmpty<TSource>(this IEnumerable<TSource> source, TSource defaultValue) 
    { 
        if (source == null) 
        { 
         throw Error.ArgumentNull("source"); 
        } 
        return DefaultIfEmptyIterator<TSource>(source, defaultValue); 
    } 
    
    public static TSource First<TSource>(this IEnumerable<TSource> source) 
    { 
        if (source == null) 
        { 
         throw Error.ArgumentNull("source"); 
        } 
        IList<TSource> list = source as IList<TSource>; 
        if (list != null) 
        { 
         if (list.Count > 0) 
         { 
          return list[0]; 
         } 
        } 
        else 
        { 
         using (IEnumerator<TSource> enumerator = source.GetEnumerator()) 
         { 
          if (enumerator.MoveNext()) 
          { 
           return enumerator.Current; 
          } 
         } 
        } 
        throw Error.NoElements(); 
    } 
    
    public static TSource FirstOrDefault<TSource>(this IEnumerable<TSource> source) 
    { 
        if (source == null) 
        { 
         throw Error.ArgumentNull("source"); 
        } 
        IList<TSource> list = source as IList<TSource>; 
        if (list != null) 
        { 
         if (list.Count > 0) 
         { 
          return list[0]; 
         } 
        } 
        else 
        { 
         using (IEnumerator<TSource> enumerator = source.GetEnumerator()) 
         { 
          if (enumerator.MoveNext()) 
          { 
           return enumerator.Current; 
          } 
         } 
        } 
        return default(TSource); 
    } 
    

這裏也有值得提及:

  1. DefaultIfEmpty有一個參數的過載,它調用的參數超載與default(TSource)並返回其結果。

  2. 無參數FirstOrDefaultFirst之間的唯一區別是後者在集合爲空時會拋出。

    有關更多信息,請參閱MSDN上的Enumerable.FirstOrDefault<TSource> Method

  3. FirstOrDefault語義表達first or default,所以叫;它的名字不是first or null。在c#中,參考類型的default(T)null,但對於非參考類型,則不是。例如,default(int)爲零。

    關鍵詞default從來沒有說過null語義上。這是默認

    另外,有關更多信息,請訪問MSDN上的default Keyword

+1

Your FirstOrDefault();最後沒有意義。如果你期望OrDefault爲空值,那麼你的序列是空的。然後「」將被返回...我建議.First()代替。 – Elisabeth

+0

@Elisa:是的,他們在這裏是一樣的,因爲我只是從代碼中複製而沒有改變,但我認爲這並不重要。 –

+0

它確實很重要。使用FirstOrDefault只有50%是正確的。 OrDefault(空值)永遠不會發生,給讀者一個錯誤的印象,即代碼在做什麼。 – Elisabeth