枚举[]是的IEnumerable< INT>在一个通用的方法返回true [英] enum[] is IEnumerable<int> returns true in a generic method

查看:113
本文介绍了枚举[]是的IEnumerable< INT>在一个通用的方法返回true的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个后续到这个问题:的演员LT; INT> .Cast<&诠释GT;应用于无效强制转换异常通用枚举集合结果

 枚举性别{男,女} 

性别G = Gender.Male;

布尔B = g为INT; //假,好吗没有问题
B =新[] {G}是IEnumerable的< INT取代; //假,好吗没有问题
B =为<性别,INT>(七); //假,好吗没有问题
B =为<性别[],IEnumerable的< INT>>(新[] {G}); //真的,为什么在地球上!

静态布尔为< S,T>(S S)
{
返回小号为T;
}



这是为什么性别[]是的IEnumerable< INT> ; 收益真正在一般情况下? ?尤其是当它们不兼容键入

 的IEnumerable< INT> C =新[] {} Gender.Male; //没有编译



这绊倒了我,我联系的问题!我认为这个问题是联系在一起的问题问题的症结所在。






有关感兴趣的人,这是一个极端例子使用数组(不是真的枚举)。按照答案埃里克利珀的博客文章知道更多的这种优势的情况下。这不符合列表与LT发生; T> 例如:

  b =为<列表与LT;性别>中的IEnumerable< INT>>(新的List<性别与GT; {G}); //假的,正确


解决方案

我觉得这是一个这些情况下,的C#定义 isinst 的CLI的定义,这显然是把枚举作为其基础的基本区别数组赋值兼容性检查时输入。 (埃里克利珀写了的博客文章这可以解释为什么 UINT [] 由CLI视为一个 INT [] ,但。不是C#;我怀疑了相同的解释适用于这里)你甚至不需要泛型证明:

 性别G = Gender.Male; 
Console.WriteLine(新[] {G}是IEnumerable的< INT>); //假
Console.WriteLine((对象)新[] {G}是IEnumerable的< INT>); //真



第一个表达优化编译时间的,因为C#编译器知道性别[] ISN 'T的的IEnumerable< INT> 。第二个表达产生一个在评估一个 isinst 指令的运行时间的。引用埃里克利珀:




不幸的是,C#和CLI的规格不同意这个小点,但我们愿意忍受不一致。



This is a followup to this question: Cast<int>.Cast<int?> applied on generic enum collection results in invalid cast exception

enum Gender { Male, Female }

Gender g = Gender.Male;

bool b = g is int; // false, alright no issues
b = new[] { g } is IEnumerable<int>; // false, alright no issues
b = Is<Gender, int>(g); //false, alright no issues
b = Is<Gender[], IEnumerable<int>>(new[] { g }); // true, why on earth !!!

static bool Is<S, T>(S s)
{
    return s is T;
}

Why is that Gender[] is IEnumerable<int> returns true in the generic case? Especially when they are not type compatible?

IEnumerable<int> c = new[] { Gender.Male }; //not compilable

It had tripped me in the question I linked! I think this question is the crux of the issue of the linked question.


For someone interested, this is a corner case with arrays (not really enums). Follow Eric Lippert's blog article in the answer to know more of this edge case. This doesn't happen with List<T> for instance:

b = Is<List<Gender>, IEnumerable<int>>(new List<Gender> { g }); // false, rightly

解决方案

I think this is one of those cases where the C# definition of is differs from the CLI's definition of isinst, which evidently treats enums as their underlying base type when checking for array assignment compatibility. (Eric Lippert wrote a blog post that explains why uint[] is treated as an int[] by the CLI but not by C#; I suspect the same explanation applies here.) You don't even need generics to demonstrate:

Gender g = Gender.Male;
Console.WriteLine(new[] { g } is IEnumerable<int>); // False
Console.WriteLine((object)new[] { g } is IEnumerable<int>); // True

The first is expression is optimized to false at compile time because the C# compiler "knows" Gender[] isn't an IEnumerable<int>. The second is expression generates an isinst instruction which is evaluated at run time. Quoting Eric Lippert:

It is unfortunate that C# and the CLI specifications disagree on this minor point but we are willing to live with the inconsistency.

这篇关于枚举[]是的IEnumerable&LT; INT&GT;在一个通用的方法返回true的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆