Как 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 является типом поддержки для перечисления.