Enum [] является IEnumerable <int> возвращает true в общем методе
Это следующий вопрос к этому вопросу: 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
Это смутило меня в вопросе, который я связал! Я думаю, что этот вопрос является основной проблемой связанного вопроса.
Для кого-то, кого это интересует, это угловой случай с массивами (на самом деле нет перечислений). Следуйте блог Эрика Липперта в ответ, чтобы узнать больше об этом случае. Это не происходит с List<T>
, например:
b = Is<List<Gender>, IEnumerable<int>>(new List<Gender> { g }); // false, rightly
Ответы
Ответ 1
Я думаю, что это один из тех случаев, когда определение С# is
отличается от определения CLI isinst
, которое, по-видимому, рассматривает перечисления как их базовый тип при проверке совместимости присвоений массивов. (Эрик Липперт написал сообщение в блоге, в котором объясняется, почему uint[]
рассматривается как int[]
CLI, но не С#; я подозреваю, что здесь применяется такое же объяснение. ) Вам даже не нужны дженерики, чтобы продемонстрировать:
Gender g = Gender.Male;
Console.WriteLine(new[] { g } is IEnumerable<int>); // False
Console.WriteLine((object)new[] { g } is IEnumerable<int>); // True
Первое выражение is
оптимизировано на false
во время компиляции, потому что компилятор С# "знает" Gender[]
не является IEnumerable<int>
. Второе выражение is
генерирует инструкцию isinst
, которая оценивается во время выполнения. Цитирование Эрика Липперта:
К сожалению, спецификации С# и CLI не согласны с этой незначительной точкой, но мы готовы жить с несогласованностью.