О чем здесь спрашивают, мне не совсем ясно, но я надеюсь, что теперь понял.
Учитывая приведенный ниже код:
void F(Object obj) {
var isEnum obj is Enum;
...
}
В каких частях стандарта C# указано, что isEnum
истинно, когда obj
является экземпляром перечисляемого типа?
В 14.9.10 это оператор в Спецификация языка C# содержит пять пунктов, описывающих, как он оценивается:
Первый пункт касается случаев, когда obj
имеет более конкретный тип, чем System.Object
.
Второй пункт касается типов, допускающих значение NULL.
Четвертая пуля посвящена универсальным типам.
Пятая пуля — это когда совпадений нет, а оператор is
оценивается как false, чего, как мы знаем, нет.
Вы ожидаете, что третий пункт относится к приведенному выше коду. Третья пуля состоит из четырех подпунктов:
1-й подпункт применяется, когда obj
равно нулю.
Второй подпункт посвящен типам, допускающим значение NULL.
Четвертый подпункт — это когда совпадений нет, а оператор is
оценивается как false, чего, как мы знаем, нет.
Вы ожидаете, что применяется третий подпункт:
В противном случае пусть R будет типом времени выполнения экземпляра, на который ссылается e. Если R и T имеют один и тот же тип, если R является ссылочным типом и существует неявное преобразование ссылки из R в T, или если R является типом значения, а T является типом интерфейса, реализованным R, результат будет истинным.
Тем не менее, кажется, что здесь отсутствует что-то особенное в типах enum. Предполагая, что obj
является экземпляром типа перечисления MyEnum
, ни одно из предложений не соответствует приведенному выше коду:
R и T не одного типа, потому что R — это MyEnum
, а T — это System.Enum
.
R — это MyEnum
, который является типом значения (11.1.9), а не ссылочным типом.
T — это System.Enum
, который не является типом интерфейса.
Я не хочу утверждать, что в спецификации есть ошибка, но после подробного прочтения 14.9.10 я не могу понять, как is Enum
может быть оценено как true, учитывая коробочную ссылку на тип перечисления.
Зная, что люди, занимающиеся стандартами, в целом намного умнее меня, я, вероятно, что-то упустил из виду, но даже если бы я этого не сделал, это не должно мешать вам использовать is Enum
для проверки того, является ли тип перечислением. Я уверен, что это не деталь реализации, которую можно использовать таким образом.
person
Martin Liversage
schedule
07.02.2012
typeof(Enum).IsValueType => false
- person leppie   schedule 07.02.2012Enum
или определенных пользователем перечислениях? Кажется, есть небольшая путаница (включая меня; p) - person leppie   schedule 07.02.2012Enum
? Это более или менее абстрактный класс. - person sq33G   schedule 08.02.2012