4

所以我试图弄清楚传递给我的方法的任何随机 IEnumerable 是否已被分组。我的想法是我将以不同的方式处理分组数据。我的问题是IGrouping<>一个通用接口,它没有实现非通用接口,无论出于何种原因,我都无法用is语句对其进行测试。

在这里测试一下是我的示例代码:

        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 框架中的错误吗?

以上结果怎么可能?


编辑:Jon Skeet 的回答已经死了......作为对其他发现自己遇到同样困难的人的礼貌,以下代码完成了检查 IEnumerable 是否被分组的工作(基于 Mr . Skeet 使用 dynamic 关键字的奇思妙想):

    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
4

1 回答 1

10

结果不仅是可能的,而且在 .NET 4 下是预期的 - 在 .NET 3.5 中,由于缺乏通用差异,最终结果将是 False。

While在 和IGrouping<out TKey, out TValue>中都是协变的TKeyTValue,KeyValuePair<Tkey, TValue>是一个结构体,因此不能以协变的方式使用。

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

不是框架中的错误。至于如何确定某些东西是否IGrouping<TKey, TValue>适用于某些TKey, TValue配对,您可以自己努力工作,或者使用dynamicto 尝试帮助:

// 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");
}

请注意,这当然不是万无一失的 - 但它可能足以满足您的需要。

于 2012-02-02T20:47:12.710 回答