2011-12-30 2 views
5

Я понимаю, что Enums скомпилированы как константы, поэтому их изменение приводит к нарушению изменения. Мне интересно, почему же не перечислил Enums так же, как статические переменные readonly?Почему Enums были скомпилированы как константы вместо статических значений?

+1

Значения Enum не могут меняться во время выполнения таким же образом, как и can not const.Если они были статическими, это означало бы, что их значение может измениться. –

ответ

6

Они могут быть более эффективными, чем поля, поэтому нет необходимости составлять их таким же образом, когда они могут быть непосредственно встроены в IL.

[Enums] загружаются в тот же способ загрузки значения const. Они встроены непосредственно в IL-код . С другой стороны, полям требуется инструкция полевой нагрузки (ldsfld), которая будет несколько влиять на производительность. Таким образом, перечислены так же быстро, как const при типичном использовании; поля несколько медленнее.

(Source)

+0

Хорошо, так что это было решение, основанное на производительности. Это именно то, что я искал ... ответ на вопрос «Почему?». –

1

От enum (C# Reference)

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

Так что я что-то упускаю?

+0

Да. Вопрос: «Почему они компилируются как константы вместо статических readonlys?» ... В основном, каково было конструктивное решение сделать их постоянными литералами вместо статических readonlys? –

+0

@my, Если я не ошибаюсь, readonly может быть установлен в Instantiation, и это не то же самое, что константы, которые невозможно установить в Instantiation –

8

Оба эти ответы технически правильны, но не дают объяснений различительных констант со статикой (только для чтения). В C#, константы всегда быстрее, чем только для чтения, и причина очень проста и лучше всего выражается с небольшим кодом, например:

const int MyConstant = 10; 
static readonly int MyReadonly = 20; 

static void Main() 
{ 
    int result = MyConstant + MyReadonly; 
    // the above statement will be resolved to: 
    // int result = 10 + MyReadonly 
} 

Во время компиляции, компилятор заменяет все ссылки на константу с фактическим значением этого постоянная , Он может это сделать, потому что константа должна быть предопределена во время компиляции. Это отличается от статических значений readonly, которые, хотя и статичны, фактически разрешены во время выполнения. Рассмотрим следующий пример:

static readonly Encoding = Encoding.GetEncoding("GB2132"); 

Там нет никакого способа для компилятора знать, если GB2132 действительно существует на машине, на которой этот код предназначен для запуска. Единственный способ разрешить это значение - во время выполнения. Static гарантирует, что само значение не привязано к времени жизни экземпляра и readonly гарантирует, что значение может быть установлено только один раз. Компилятор не может заменить ссылки на это поле во время компиляции, так как значение просто невозможно узнать.

Логически только примитивные типы могут быть отмечены как постоянные.

Теперь в случае перечислений это очень просто. Перечисления - это не что иное, как целочисленное значение с меткой. Таким образом, следующий код:

enum MyEnum 
{ 
    First, 
    Second, 
    Third 
} 

static void Main() 
{ 
    MyEnum test = MyEnum.First; 

    if (test == MyEnum.Second) 
    { 
     // whatever 
    } 
} 

Будет решена компилятором:

const int MyEnum_First = 0; 
const int MyEnum_Second = 1; 
const int MyEnum_Third = 2; 

static void Main() 
{ 
    int test = MyEnum_First; 

    if (test == MyEnum_Second) 
    { 
     // whatever 
    } 
} 

Что в свою очередь означает, что фактические ссылки на постоянные поля могут быть заменены значением, известным во время компиляции, что делает окончательная версия кода:

static void Main() 
{ 
    int test = 0; 

    if (test == 1) 
    { 
     // whatever 
    } 
} 
+0

Удивительное объяснение, чувак – ivowiblo

+0

Да, но вопрос был не в том, почему Enums нарушают изменения, но почему Microsoft решила скомпилировать их как константы вместо статических полей readonly. Они могли бы заставить компилятор пойти в любом случае, вопрос в том, почему они пошли с константами, а не тогда, когда это было бы изменением, и кто-то ответил на это ... просто для повышения производительности. –

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