X это enum - это согласно спецификации? - PullRequest
2 голосов
/ 07 февраля 2012

Проверка, является ли объект перечислением обсуждает проверку объекта с помощью is Enum, чтобы проверить, содержит ли оно значение перечисления.

Это указано где-нибудь в спецификации? Запись в is (7.10.10 в версии 4.0) перечисляет следующие возможные правые значения:

  • анонимная функция
  • группа методов
  • пустой
  • тип ссылки ** Это может быть перечисление?
  • обнуляемый тип
  • тип значения, не обнуляемый ** Это может быть перечисление?

Предполагая, что значение перечисления соответствует «ссылочному типу» из списка выше - спецификация гласит следующее:

... результат верен, если D [динамический тип RHS)] и T [LHS] одного типа, если D является ссылочным типом и существует неявное ссылочное преобразование из D в T, или если D является типом значения и существует преобразование бокса из D в T.

Являются ли какие-либо из этих условий строго верными для is Enum? Например, компилятор не поддерживает is class или is struct.

Так что поддержка is Enum соответствует спецификации, или это решение о реализации?

Ответы [ 4 ]

1 голос
/ 08 февраля 2012

Нет поддержки is class или is struct, потому что нет общего базового типа, который бы отличал классы или структуры от других типов.is Enum работает, потому что System.Enum является фактическим типом, который является основой всех перечислений.И Enum является ссылочным типом, поэтому применяется последняя часть:

, если D является типом значения и существует преобразование в бокс из D в T

D (тип выражения слева) является типом значения.И T - это Enum, который является базовым типом D.Таким образом, происходит преобразование в боксе из D в Enum, и поэтому значение выражения равно true.

Преобразование в бокс из любого перечисления в Enum явно указано в §14.4. Система.Enum type:

Тип System.Enum является абстрактным базовым классом всех типов перечислений (он отличается от базового типа типа перечисления и отличается от него), а члены наследуются от System.Enum доступны в любом типе enum.Существует преобразование бокса из любого типа перечисления в System.Enum, а преобразование из распаковки существует из System.Enum в любой тип перечисления.

Обратите внимание, что System.Enum само по себе не является типом перечисления .Скорее, это тип класса , из которого получены все тип enum s.Тип System.Enum наследуется от типа System.ValueType, который, в свою очередь, наследуется от типа object.Во время выполнения значение типа System.Enum может быть нулевым или указывать на коробочное значение любого типа перечисления.

0 голосов
/ 07 февраля 2012

Enum - это фактический тип, в отличие от класса и структуры.Следовательно, Enum может использоваться с правой стороны, а класс и структура не могут.

0 голосов
/ 07 февраля 2012

Enum является ссылочным типом.

typeof(Enum).IsValueType => false

Интересно, что

typeof(ValueType).IsValueType => false
0 голосов
/ 07 февраля 2012

То, что спрашивают здесь, не совсем понятно для меня, но я надеюсь, что я получил это сейчас.


Учитывая код ниже:

void F(Object obj) {
  var isEnum obj is Enum;
  ...
}

Какие частиСтандарт C # указывает, что isEnum имеет значение true, когда obj является экземпляром типа enum?


В 14.9.10 является оператор в спецификации языка C # есть пять маркеров, описывающих, как он оценивается:

  • 1-й пункт относится к случаям, когда obj имеет более конкретный тип, чем System.Object.

  • 2-я пуля относится к обнуляемым типам.

  • 4-я пуля относится к универсальным типам.

  • 5-я пуляэто когда совпадений нет, а оператор is оценивает значение false, что, как мы знаем, нет.

Можно ожидать, что 3-й пункт относится к приведенному выше коду.3-я пуля имеет четыре подпункта:

  • 1-я подпункт применяется, если obj является нулевым.

  • 2-й подпунктbullet относится к обнуляемым типам.

  • 4-й подпункт - это когда совпадений нет, а оператор is оценивает значение false, что, как мы знаем, нет.

Можно ожидать, что применяется третий подпункт:

В противном случае, пусть R будет типом времени выполнения экземпляра, на который ссылается e.Если R и T одинакового типа, если R является ссылочным типом и существует неявное ссылочное преобразование из R в T, или если R является типом значения, а T является типом интерфейса, который реализован с помощью R, результат равен true.

Тем не менее, здесь есть что-то особенное в типах перечислений, отсутствующих здесь.Предполагая, что obj является экземпляром типа enum MyEnum, ни одно из предложений не соответствует приведенному выше коду:

  • R и T не совпадают, поскольку R равен MyEnum, а Tравен System.Enum.

  • R равен MyEnum, который является типом значения (11.1.9), а не ссылочным типом.

  • T это System.Enum, который не является типом интерфейса.

Я не хочу утверждать, что в спецификации есть ошибка, но после подробного прочтения 14.9.10 IЯ не могу понять, как is Enum может оценить как истинное, если указать в штучной упаковке ссылку на тип перечисления.

Зная, что люди, работающие в области стандартов, в целом намного умнее меня, я, вероятно, что-то упустил, но даже если бы я неЭто не должно помешать вам использовать is Enum для проверки, является ли тип перечислением.Я уверен, что это не деталь реализации, которую можно использовать следующим образом.

...