Edit : Комментарии внизу. Кроме того, это .
Вот что меня смущает. Я понимаю, что если у меня есть такое перечисление ...
enum Animal
{
Dog,
Cat
}
... то, что я, по сути, сделал, это определение типа значения с именем Animal
с двумя определенными значениями, Собака
и Кот
. Этот тип является производным от ссылочного типа System.Enum
(то, что типы значений обычно не могут делать - по крайней мере, не в C # - но что разрешено в этом случае), и имеет возможность для приведение в / из значений int
.
Если бы способ, который я только что описал выше, был верен, то я ожидал бы, что следующий код вызовет исключение InvalidCastException
:
public class Program
{
public static void Main(string[] args)
{
// Box it.
object animal = Animal.Dog;
// Unbox it. How are these both successful?
int i = (int)animal;
Enum e = (Enum)animal;
// Prints "0".
Console.WriteLine(i);
// Prints "Dog".
Console.WriteLine(e);
}
}
Обычно вы не можете распаковать тип значения из System.Object
как что-либо кроме его точного типа . Итак, как это возможно? Это как если бы тип Animal
был int
(а не только конвертируемый в int
) и ] является Enum
(а не только конвертируемым в Enum
) одновременно. Это множественное наследование? System.Enum
каким-то образом наследуется от System.Int32
(чего я не ожидал, что это возможно)?
Edit : Это не может быть ни одним из над. Следующий код убедительно демонстрирует это (я думаю):
object animal = Animal.Dog;
Console.WriteLine(animal is Enum);
Console.WriteLine(animal is int);
Вышеуказанные результаты:
True False
Как документация MSDN по перечислениям , так и спецификация C # используют термин «базовый тип»; но я не знаю, что это значит, и никогда не слышал, чтобы это использовалось в отношении чего-либо, кроме перечислений. Что на самом деле означает «базовый тип» ?
Итак, это еще один случай , который получает особую обработку со стороны CLR ?
Мои деньги на это. .. но ответ / объяснение было бы неплохо.
Обновление : Damien_The_Unbeliever предоставил ссылку, чтобы правильно ответить на этот вопрос. Объяснение можно найти в Разделе II спецификации CLI, в разделе перечислений:
Для целей привязки (например, для но я не знаю, что это значит, и никогда не слышал, чтобы это использовалось в отношении чего-либо, кроме перечислений. Что на самом деле «базовый тип» означает ?
Итак, это еще один случай , который получает особую обработку со стороны CLR ?
Мои деньги на это. .. но ответ / объяснение было бы неплохо.
Обновление : Damien_The_Unbeliever предоставил ссылку, чтобы правильно ответить на этот вопрос. Объяснение можно найти в Разделе II спецификации CLI, в разделе перечислений:
Для целей привязки (например, для но я не знаю, что это означает, и я никогда не слышал, чтобы это использовалось в отношении чего-либо, кроме перечислений. Что на самом деле «базовый тип» означает ?
Итак, это еще один случай , который получает особую обработку со стороны CLR ?
Мои деньги на это. .. но ответ / объяснение было бы неплохо.
Обновление : Damien_The_Unbeliever предоставил ссылку, чтобы правильно ответить на этот вопрос. Объяснение можно найти в Разделе II спецификации CLI, в разделе перечислений:
Для целей привязки (например, для это еще один случай, который получает особую обработку со стороны CLR ?
Мои деньги на этот случай ... но ответ / объяснение было бы неплохо.
Обновление : Damien_The_Unbeliever предоставил ссылку, чтобы верно ответить на этот вопрос. Объяснение можно найти в Разделе II спецификации CLI, в разделе перечислений:
Для целей привязки (например, для это еще один случай, который получает особую обработку со стороны CLR ?
Мои деньги на этот случай ... но ответ / объяснение было бы неплохо.
Обновление : Damien_The_Unbeliever предоставил ссылку, чтобы верно ответить на этот вопрос. Объяснение можно найти в Разделе II спецификации CLI, в разделе перечислений:
Для целей привязки (например, для поиск определения метода из ссылка на метод, использованная для его вызова) перечисления должны отличаться от их базовый тип. Для всех остальных целей, включая проверку и выполнение кода, распакованное перечисление свободно взаимодействует со своими базовый тип . Перечисления могут быть помещены в коробку к соответствующему экземпляру в штучной упаковке тип, но этот тип не то же самое как коробочный тип базового типа, поэтому бокс не теряет исходный тип перечисления.
Правка (снова?!) : Постойте, вообще-то, я не знаю, правильно ли я прочитал это в первый раз. Возможно, это не на 100% объясняет специализированное поведение распаковки (хотя я оставляю ответ Дэмиена принятым, поскольку он проливает много света на эту проблему). Я продолжу изучать это ...
Другое редактирование : Чувак, тогда ответ yodaj007 бросил меня в еще один цикл. Почему-то перечисление не совсем то же самое, что
int
; ноint
можно присвоить переменной перечисления без приведения ? Ба?Я думаю, что все это в конечном итоге освещено ответом Ганса , поэтому я принял его. (Извини, Дэмиен! )