2012-02-02 21 views
4

的時候所以我想弄清楚,如果一些任何隨機的IEnumerable傳遞給我的方法已經被越來越分組一些瘋狂的結果。這個想法是,我將以不同方式處理分組數據。我的問題是IGrouping<>是一個通用接口,沒有實現非通用接口,無論出於何種原因,我無法使用is語句對其進行測試。檢測,如果一個IEnumerable <T>進行分組,我檢查了各類

爲了驗證這一點,這裏是我的示例代碼:

 var dict = new Dictionary<int, string>() { 
      {1, "Prime" }, 
      {2, "Prime" }, 
      {3, "Prime" }, 
      {4, "Not" }, 
      {5, "Prime" }, 
      {6, "Not" }, 
      {7, "Prime" }, 
      {8, "Not" }, 
      {9, "Not" }, 
      {10, "Not" }, 
      {11, "Prime" } 
     }; 
     var grouped = from d in dict 
         group d by d.Value into gd 
         select gd; 
     Debug.WriteLine("IEnumerable<IGrouping<string, KeyValuePair<int, string>>>: {0}", grouped is IEnumerable<IGrouping<string, KeyValuePair<int, string>>>); 
     Debug.WriteLine("IEnumerable<IGrouping<object, KeyValuePair<int, string>>>: {0}", grouped is IEnumerable<IGrouping<object, KeyValuePair<int, string>>>); 
     Debug.WriteLine("IEnumerable<IGrouping<object, KeyValuePair<object, object>>: {0}", grouped is IEnumerable<IGrouping<object, object>>); 
     Debug.WriteLine("IEnumerable<IGrouping<object, object>: {0}", grouped is IEnumerable<IGrouping<object, object>>); 
     Debug.WriteLine("IEnumerable<object>: {0}", grouped is IEnumerable<object>); 

輸出如下:

IEnumerable<IGrouping<string, KeyValuePair<int, string>>>: True 
IEnumerable<IGrouping<object, KeyValuePair<int, string>>>: True 
IEnumerable<IGrouping<object, KeyValuePair<object, object>>: False 
IEnumerable<IGrouping<object, object>: False 
IEnumerable<object>: True 

如此看來,除非我知道值的類型分組,我可以不測試看它是否被分組?這是.Net框架中的一個錯誤嗎?

怎樣高於甚至有可能的結果?


編輯:喬恩斯基特的回答就死了......爲了尊重別人,在這裏找到自己與我有同樣的困難,下面的代碼做檢查的工作,看看一個IEnumerable是(基於關使用動態關鍵字的碟先生的花式屁股想法的)分組或不:

public static bool IsGrouped (dynamic test) { 
     return CheckGrouping(test); 
    } 
    static bool CheckGrouping(object o) { 
     return false; 
    } 
    static bool CheckGrouping<TKey, TValue>(IEnumerable<IGrouping<TKey, TValue>> grouping) { 
     return true; 
    } 

假設代碼是與上述相同的:

IsGrouped(dict); //false 
IsGrouped(grouped); //true 

回答

10

結果不僅是可能的,但預期下.NET 4 - 在.net 3.5,最終的結果將是虛假由於缺乏通用的方差。

雖然IGrouping<out TKey, out TValue>在兩個TKeyTValue協變,KeyValuePair<Tkey, TValue>是一個結構,並且因此不能在協變的方式使用。

所以IGrouping<string, string>IGrouping<object, object>,但IGrouping<string, KeyValuePair<int, string>>不是。

這是框架中的一個bug。至於如何找到的東西是否對一些TKey, TValue對實現IGrouping<TKey, TValue>,你既可以工作得非常辛苦自己,或使用dynamic盡力幫助:

// Code as before... 
dynamic dyn = grouped; 
ShowGrouping(dyn); 

private static void ShowGrouping<TKey, TValue> 
    (IEnumerable<IGrouping<TKey, TValue>> grouping) 
{ 
    Console.WriteLine("TKey = {0}, TValue = {1}", typeof(TKey), typeof(TValue)); 
} 

private static void ShowGrouping(object notGrouped) 
{ 
    Console.WriteLine("Not a grouping"); 
} 

注意,這肯定不是萬無一失 - 但它可能足夠滿足你的需求。

+0

謝謝!我嘗試的第一件事實際上是IEnumerable 的擴展方法,用於分組或非分組,這並沒有真正起作用。我不認爲使用動態關鍵字。我意識到這是KVP,字符串和整數的問題,而我正在玩它,並與同事交談。 – 2012-02-02 21:08:26

+1

@blesh:'string'不是一個結構,它是一個類。 – 2012-02-02 21:14:53

+0

再次感謝您!我編輯了我的問題,包括如何使用動態關鍵字的超級聰明使用來解決我的特定問題。說實話,這是我第一次有理由使用它,很奇怪。 – 2012-02-02 21:24:46

相關問題