2015-02-25 2 views
15

Согласно this post int является типом подложки для enum.Как int является типом подложки для перечисления

Когда я проверяю исходный код .NET System.Enum абстрактный класс наследует от System.ValueType абстрактный класс.

Но когда я проверяю структуру System.Int32, она наследует от интерфейсов, но не от System.ValueType.

Наоборот, когда я декомпилировать mscorlib.dll и проверить Int32-структуру, что говорит о том, что структура имеет базовый тип System.ValueType.

enter image description here

Но все-таки проверять декомпилированный исходный код, который я не могу видеть ничего о System.ValueType.

enter image description here

Это заставляет меня думать, что ключевое слово struct делает decleration автоматический Sytem.ValueType, который Microsoft также обозначает в этом reference.

Но у меня еще вопрос. Насколько мне известно, наследование двух разных классов от одного и того же родителя не означает, что он также наследуется от другого. Я имею в виду, если B:A и C:A это не всегда означает, что C:B.

Кроме того, когда я проверяю исходные коды, System.Enum имеет совершенно другую реализацию от System.Int32.

Назад к истокам, в этих обстоятельствах, как это происходит, к результату, что «System.Int32» является типом поддержки для System.Enum?

Может ли кто-нибудь объяснить?

С уважением.

+2

См. Http://stackoverflow.com/a/3504145/1625737 – haim770

+3

«Все типы значений выводятся ** неявно ** из System.ValueType». (Https://msdn.microsoft.com/en-us/library/s1ax56ch.aspx). – haim770

+2

Определенно не вне темы. Вы можете удалить P.S часть :) –

ответ

9

Int32 - это только базовый тип по умолчанию для перечисления, однако это изменчиво. Вы можете изменить это, указав другой тип данных, например.

enum ExampleEnum : byte 
{ 
    Value1, 
    Value2, 
    Value3 
}; 

Вот что говорит Microsoft по поводу перечисления:

Каждый тип перечисления имеет базовый тип, который может быть любой интегральный тип за исключением гольца.
Элемент перечисления по умолчанию, используемый по умолчанию, - int.
Чтобы объявить перечисление другого интегрального типа, например, байты, использовать двоеточие после идентификатора с последующим типом,
...
Одобренными типами для перечисления является байты, SByte, короткий, USHORT, Int, uint, long или ulong.

^Source MSDN: enum (C# Reference)

+0

спасибо @AeroX. – user3021830

1

int и enum - две разные вещи, например, вы можете вычислить (добавить/вычесть) целые числа, которые вы не можете сделать с перечислениями. Поэтому ясно, что имплантация обоих очень различна.

По-прежнему перечисление хранится так же, как целое число (обычно это 32-битная ячейка памяти), и существует преобразование 1: 1 между значениями перечисления и значениями int.

В этом смысле int является тип подкачки для перечисления.

+0

Большое спасибо за помощь @DrKoch. Это было полезно. – user3021830

12

Ты путаешь 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 эффективно определяется как (псевдо-код, не действует C#)

struct Foo : Enum { 
    int value__; 
} 

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

Тип подложки определяется как часть каждого конкретного типа перечисления, а не как часть System.Enum. Этого не может быть, потому что это может быть разным для двух разных типов перечисления.

+0

Большое спасибо за ваше объяснение @hvd. – user3021830

3

Вы отключаетесь из-за разницы между Наследование и Представление.

Только потому, что B наследует от A, это не означает, что B представлен (поддерживается) A.

Enum может наследовать от ValueType, но будет представлен (поддерживается) int.

Это немного похож на Person класс может наследовать от Object она использует string (Name) и int (Возраст) в качестве типов отступающих для класса.

Важным, фундаментальным моментом является то, что компилятор делает немного магии при работе с несколькими типами. ValueType наследует от Object, но это не ссылочный тип, потому что компилятор имеет дело с ним специально.

Enum является специальным ValueType, который имеет автоматически созданный фоновый код - int по умолчанию - и все это зависит от компилятора.

+0

Большое спасибо за ваши усилия @ Энигматичность. – user3021830

Смежные вопросы