![](/img/trans.png)
[英]How to write a method that takes an enum as a generic and returns the int value
[英]enum[] is IEnumerable<int> returns true in a generic method
这是此问题的后续内容: 对通用枚举集合应用的Cast <int> .Cast <int?>会导致无效的强制转换异常
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;
}
为什么Gender[] is IEnumerable<int>
在通用情况下返回true
? 特别是当它们不兼容时?
IEnumerable<int> c = new[] { Gender.Male }; //not compilable
在我链接的问题中,它让我感到惊讶! 我认为这个问题是相关问题问题的症结所在。
对于有兴趣的人来说,这是一个带有数组(不是真正的枚举)的极端情况。 在答案中关注Eric Lippert的博客文章,了解更多这个边缘案例。 例如, List<T>
不会发生这种情况:
b = Is<List<Gender>, IEnumerable<int>>(new List<Gender> { g }); // false, rightly
我认为这是其中的C#定义的那些情况下一个is
从的CLI的定义不同isinst
,对于阵列分配兼容性检查时显然对待枚举作为其底层的基类型。 (Eric Lippert撰写了一篇博客文章 ,解释了为什么uint[]
被CLI视为int[]
,而不是C#;我怀疑同样的解释适用于此。)你甚至不需要泛型来证明:
Gender g = Gender.Male;
Console.WriteLine(new[] { g } is IEnumerable<int>); // False
Console.WriteLine((object)new[] { g } is IEnumerable<int>); // True
第一个is
在编译时将表达式优化为false
,因为C#编译器“知道” Gender[]
不是IEnumerable<int>
。 第二个is
表达式生成一个isinst
指令,在运行时进行评估。 引用Eric Lippert:
遗憾的是C#和CLI规范在这个小问题上存在分歧,但我们愿意忍受不一致。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.