Как int - тип поддержки для перечисления
Согласно this post int
является типом поддержки для enum
.
Когда я проверяю исходный код .NET System.Enum абстрактный класс наследует от System.ValueType абстрактный класс.
Но когда я проверяю System.Int32 struct, он наследует от интерфейсов, но не от System.ValueType.
Напротив, когда я декомпилирую mscorlib.dll и проверяю структуру Int32
, он говорит, что структура имеет базовый тип System.ValueType
.
![enter image description here]()
Но все еще проверяя декомпилированный исходный код, я ничего не вижу о System.ValueType
.
![enter image description here]()
Мне кажется, что ключевое слово struct
делает объявление auto-Sytem.ValueType, которое Microsoft также обозначает в ссылка.
Но у меня все еще есть вопрос. Насколько мне известно, наследование двух разных классов от одного и того же родителя не означает, что он также наследуется от другого. Я имею в виду, если B:A
и C:A
это не всегда означает, что C:B
.
Кроме того, когда я проверяю исходные коды, System.Enum
имеет совсем другую реализацию из System.Int32
.
Возвращаясь к истокам, в этих обстоятельствах, как это происходит, результат "System.Int32" является типом поддержки для System.Enum
?
Может ли кто-нибудь объяснить?
С уважением.
Ответы
Ответ 1
Int32 - это только базовый тип по умолчанию для перечисления, однако это изменчиво. Вы можете изменить это, указав другой тип данных, например.
enum ExampleEnum : byte
{
Value1,
Value2,
Value3
};
Вот что говорит Microsoft относительно перечисления:
Каждый тип перечисления имеет базовый тип, который может быть любым целым типом, кроме char.
Основной тип элементов перечисления по умолчанию - int.
Чтобы объявить перечисление другого целочисленного типа, например байта, используйте двоеточие после идентификатора, за которым следует тип,
...
Утвержденными типами перечисления являются байт, sbyte, short, ushort, int, uint, long или ulong.
^ Источник MSDN: перечисление (ссылка С#)
Ответ 2
Вы вводите в заблуждение enum
(ключевое слово С# для определения типа перечисления) и enum
(класс, из которого происходит такой тип перечисления).
using System;
using System.Reflection;
enum Foo { A, B, C };
static class Program {
static void Main() {
foreach (var field in typeof(Foo).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
Console.WriteLine("Found instance field \"" + field.Name + "\" of type \"" + field.FieldType.FullName + "\"");
}
}
В моей системе это печатает
Found instance field "value__" of type "System.Int32"
Это потому, что Foo
эффективно определяется как (псевдокод, недействительный С#)
struct Foo : Enum {
int value__;
}
вместе с некоторой дополнительной поддержкой компилятора, некоторые дополнительные статические поля для перечисления членов перечисления, но основная идея остается той же.
Тип поддержки определяется как часть каждого конкретного типа перечисления, а не как часть System.Enum
. Этого не может быть, потому что это может быть разным для двух разных типов перечисления.
Ответ 3
Вы отключаетесь из-за разницы между наследованием и представлением.
Просто потому, что B
наследуется от A
, это не означает, что B
представляется (поддерживается) A
.
An Enum
может наследовать от ValueType
, но быть представлен (поддерживается) на int
.
Это немного похоже на класс Person
, который может наследовать от Object
, он использует string
(Name) и int
(Age) в качестве типов поддержки для класса.
Важным, фундаментальным моментом является то, что компилятор делает немного магии при работе с несколькими типами. ValueType
наследует от Object
, но это не ссылочный тип, потому что компилятор имеет дело с ним специально.
An Enum
- это специальный ValueType
, который имеет автоматически созданный тип поддержки - int
по умолчанию - и все это зависит от компилятора.
Ответ 4
int
и enum
- две разные вещи, например, вы можете вычислить (добавить/вычесть) целые числа, которые вы не можете сделать с перечислениями. Поэтому ясно, что имплантация обоих очень различна.
Тем не менее, перечисление сохраняется так же, как целое число (обычно это 32-битная ячейка памяти), и существует преобразование 1:1 между значениями перечисления и значениями int.
В этом смысле int является типом поддержки для перечисления.