检测IEnumerable<;T>;已分组,I';我在检查类型时得到了一些疯狂的结果
本文关键字:类型 检查 结果 疯狂 gt lt IEnumerable 检测 | 更新日期: 2023-09-27 18:22:31
所以我试图弄清楚传递给我的方法的一些随机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 Framework中的错误吗?
上面的结果怎么可能呢?
编辑:Jon Skeet的回答完全正确……作为对其他发现自己在这里遇到同样困难的人的礼貌,以下代码完成了检查IEnumerable是否分组的工作(基于Skeet先生使用动态关键字的绝妙想法):
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
在.NET 4下,结果不仅是可能的,而且是预期的-在.NET 3.5中,由于缺乏通用方差,最终结果将为False。
虽然IGrouping<out TKey, out TValue>
在TKey
和TValue
中都是协变的,但KeyValuePair<Tkey, TValue>
是一个结构,因此不能以协变的方式使用。
所以IGrouping<string, string>
是IGrouping<object, object>
,但IGrouping<string, KeyValuePair<int, string>>
不是。
这不是框架中的错误。至于如何找出某个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");
}
请注意,这当然不是万无一失的,但它可能足以满足您的需求。