枚举[]是IEnumerable< int>在通用方法中返回true [英] enum[] is IEnumerable<int> returns true in a generic method
问题描述
这是对这个问题的追踪:演员LT; INT> .Cast<诠释>应用于通用枚举收集结果无效转播例外
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;
}
为什么 Gender []是IEnumerable< int> ;在通用情况下
返回 true
特别是当它们不兼容时?
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.
对于有兴趣的人来说,这是一个角落数组(不是真的枚举)。按照 Eric Lippert的博客文章在答案中了解更多的这种边缘案例。例如, List< T>
不会发生这种情况:
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
推荐答案
我认为这是那些的C#定义
不同于CLI的定义 isinst
,这显然将枚举作为它们的基础检查数组分配兼容性时键入。 (Eric Lippert写了一个 uint [] 被CLI视为一个 int []
不是C#;我怀疑这里也有相同的解释)你甚至不需要泛型来证明:
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
第一个是
表达式由于C#编译器知道性别[]
isn被优化为 false
't an IEnumerable< int>
。第二个表达式生成运行时评估的
isinst
指令。引用Eric Lippert:
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:
不幸的是,C#和CLI规范在这个小点上不同意,但是我们愿意以不一致的方式生活。
It is unfortunate that C# and the CLI specifications disagree on this minor point but we are willing to live with the inconsistency.
这篇关于枚举[]是IEnumerable< int>在通用方法中返回true的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!