繁体   English   中英

enum []是IEnumerable <int> 在泛型方法中返回true

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM