检测 IEnumerable 是否为是分组的,在检查类型时我得到了一些疯狂的结果
所以我试图弄清楚传递给我的方法的一些随机 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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在 .NET 4 中,结果不仅是可能的,而且是预期的 - 在 .NET 3.5 中,由于缺乏通用方差,最终结果将为 False。
而
IGrouping
在TKey
和TValue
中都是协变的,KeyValuePair
是一个结构体,因此不能以协变的方式使用。因此,
IGrouping
是一个IGrouping
,但也是一个IGrouping> 不是。
这不是框架中的错误。至于如何找出某些
TKey, TValue
对是否实现了IGrouping
,你可以自己努力工作,或者使用dynamic
尝试提供帮助:请注意,这当然不是万无一失的 - 但它可能足以满足您的需要。
The results are not just possible but expected under .NET 4 - in .NET 3.5, the final result would be False due to the lack of generic variance.
While
IGrouping<out TKey, out TValue>
is covariant in bothTKey
andTValue
,KeyValuePair<Tkey, TValue>
is a struct, and therefore cannot be used in a covariant manner.So an
IGrouping<string, string>
is anIGrouping<object, object>
, but anIGrouping<string, KeyValuePair<int, string>>
is not.This is not a bug in the framework. As for how to find out whether something implements
IGrouping<TKey, TValue>
for someTKey, TValue
pair, you could either work quite hard yourself, or usingdynamic
to try to help:Note that this certainly isn't foolproof - but it may be good enough for what you need.