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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With