2011-07-25 47 views
19

我有一個方法,返回ILookup。在某些情況下,我想返回一個空的ILookup作爲提前退出。構建一個空的ILookup的最佳方法是什麼?空ILookup <K, T>

+0

你是什麼類型在您的ILookup 中用作K和T? –

回答

37

除了來自mquanderVasile Bujac的回答,您可以創建一個很好的,簡單的單例式EmptyLookup<K,E>類,如下所示。 (在我看來,似乎沒有多大的好處,以創建一個完整的ILookup<K,E>實現按瓦西里的答案。)

var empty = EmptyLookup<int, string>.Instance; 

// ... 

public static class EmptyLookup<TKey, TElement> 
{ 
    private static readonly ILookup<TKey, TElement> _instance 
     = Enumerable.Empty<TElement>().ToLookup(x => default(TKey)); 

    public static ILookup<TKey, TElement> Instance 
    { 
     get { return _instance; } 
    } 
} 
+0

感謝mquander和Vasile,但我認爲這兩種解決方案的合併最簡單/最好。 –

-1

你可以返回null

或異常

但是你要注意它的類註釋

新增:+這比一些擴展方法

+4

我完全不同意。如果一個函數返回了一個'K'到'T'的查找映射,並且碰巧沒有'K'或'T's,那麼顯然這個函數應該返回一個空的查找。返回null或拋出異常沒有任何意義,並且必須在任何地方突然檢查它,如果您返回空查找,那麼它剛剛開箱即用。 – mquander

+0

「ILookup作爲早期退出」 - 這是一個典型的情況,當你應該拋出異常。 –

+0

如果您放置註釋aboute異常,所有其他開發人員都會以樣式sence查看它。並處理該異常。 –

18

更加明顯有沒有內置,所以我只寫一個擴展方法,沿着new T[0].ToLookup<K, T>(x => default(K));

I 強烈懷疑返回null將在這裏更加正確。幾乎從來沒有這樣的情況,你想從返回一個集合的方法返回null(而不是空集合)。我不可能不同意那些暗示這個集合的人。

+0

需要考慮返回值的語義。例如,不返回結果的搜索應返回一個空集合,但具有(例如)失敗或具有無效參數的搜索應該返回「null」。 –

+3

那麼,一個搜索具有無效的參數(如,在一個方法無效的參數,我猜)可能應該拋出。但我明白你的意思。然而,一個方法返回一個空集合通常是很常見的,在這種情況下通常會返回null。 – mquander

+0

關於拋出錯誤,你的確是正確的。但是,我曾與商業應用程序合作過,例如,某些外部系統在一天中的某些時段將不可用;在這種情況下,查詢和請求會失敗,但這不是一個「例外」情況,因爲它是預期的行爲。 –

7

您可以爲空查找創建單例類。

public sealed class EmptyLookup<T, K> : ILookup<T, K> 
{ 
     private static readonly EmptyLookup<T, K> _instance 
      = new EmptyLookup<T, K>(); 

     public static EmptyLookup<T, K> Instance 
     { 
      get { return _instance; } 
     } 

     private EmptyLookup() { } 

     public bool Contains(T key) 
     { 
      return false; 
     } 

     public int Count 
     { 
      get { return 0; } 
     } 

     public IEnumerable<K> this[T key] 
     { 
      get { return Enumerable.Empty<K>(); } 
     } 

     public IEnumerator<IGrouping<T, K>> GetEnumerator() 
     { 
      yield break; 
     } 

     System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 
     { 
      yield break; 
     } 
    } 

那麼你可以這樣寫代碼:

var x = EmptyLookup<int, int>.Instance; 

創建一個新類的好處是,你可以使用「是」運營商和檢查類型相等:

if (x is EmptyLookup<,>) { 
// .... 
} 
+0

嚴格來說,這可能是最好的答案。 – mquander

+0

謝謝,看起來不錯。我會建議[]應該拋出KeyNotFoundException而不是NotImplementedException。 –

+0

是的,你說得對,謝謝。我修改了我的帖子 – Vasea

1

創建一個空列表,然後對其執行ToLookup(),如下所示:

List<Point> items = new List<Point>(); 
ILookup<int, int> lookup = items.ToLookup(p => p.X, p => p.Y); 

祝你好運!

-1

或者更多的東西LINQ的精神:

public static class Utility 
{ 

    public static ILookup<TKey, TElement> EmptyLookup<TKey, TElement>(Func<TKey, TKey> keySelector, 
                     Func<TKey, TElement> elementSelector) 
    { 
     return Enumerable.Empty<TKey>().ToLookup(keySelector, elementSelector); 
    } 

} 
+0

爲什麼即使在選擇器funcs中也需要考慮? –