Подтвердить что ты не робот

Почему значение enum по умолчанию равно 0, а не минимальное?

Какой смысл иметь "0" в качестве значения по умолчанию для перечисления в С#? Если я объявляю перечисление, которое начинается с другого номера:

enum Color
{
   Blue = 1,
   Green,
   Red,
}

then var color = default(Color) - вернет мне "0" . Я ожидал увидеть минимальное значение. Это может вызвать проблемы, если каждый член перечисления соответствует определенному числу, а "0" не является допустимым значением.

4b9b3361

Ответ 1

Мы можем только догадываться, почему аспект структуры .NET был разработан определенным образом. Для наиболее простого объяснения я хотел бы выделить это замечание из документации MSDN:

Перечисление представляет собой набор именованных констант, базовый тип которых любой интегральный тип, кроме Char. Если базовый тип явно не указан объявлен, используется Int32.

Обратите внимание, что перечисление .NET является, по существу, расширением целочисленного типа. Значение по умолчанию для интегральных типов равно 0, поэтому разумно (если несколько неудобно в тех случаях, когда вы проиллюстрировали), чтобы перечисления наследовали это поведение.

Ответ 2

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

Вот спецификация: Таблица значений по умолчанию

EDIT: для более подробной информации проверьте MSDN для типов перечисления - enum

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

Примечание: поскольку @archil указывает, что значение перечисления может содержать любое значение типа поддержки, независимо от списка констант, перечисленных в перечислении. Для перечислений с надписью "FlagsAttribute" это поведение обычно ожидается, но для обычных перечислений оно может быть неинтуитивным.

Ответ 3

Всегда существует возможность для перечисления иметь несуществующее значение. Вот почему существует Enum.IsDefined Method.

Значение по умолчанию для перечисления E является значением, выражаемым выражением (Е) 0.

Ответ 4

Как уже было сказано в нескольких ответах, значение "по умолчанию" для любой структуры данных фиксированного размера равно 0. Размер памяти структур устанавливается равным нулю и считается "по умолчанию" . Теперь, если вы хотите определить собственное значение "по умолчанию" для перечисления, у вас есть несколько вариантов. Самым простым было бы написать свою собственную функцию, чтобы дать вам "минимальное допустимое перечисление"

private E GetDefaultEnum<E>()
{
    return (E)(Enum.GetValues(typeof(E)).Cast<E>().Min<E>());
}

Использование:

enum Color
{
   Blue = 1,
   Green,
   Red,
}

Color defaultColor = GetDefaultEnum<Color>();
MessageBox.Show(defaultColor.ToString()); // "Blue"

Очевидно, вы можете изменить способ определения значения по умолчанию, но этот способ, по-видимому, наилучшим образом подходит для ваших нужд.

Ответ 5

Зачем стоит значение enum по умолчанию? Простота выполнения. По умолчанию любой тип значения является побитовым 0, и предположительно нулевая ссылка представляется побитовым 0. Таким образом, чтобы первоначально построить объект со значениями по умолчанию, нам нужно знать его размер; среда выполнения не нуждается в том, чтобы знать или обрабатывать что-либо о структуре объекта. Аналогично, предварительно определенный конструктор типа значения может просто заполнять диапазон памяти нулями.

Нравится нам это или нет, так оно и есть. Что нужно сделать в ответ - при создании перечисления, независимо от того, какое имя является подходящим значением по умолчанию, дайте ему значение 0. Если подходящего значения по умолчанию нет, то ваши методы, принимающие такое перечисление как параметр, могут проверить, что он правильно установлен, например,

void ProcessColor(Color c) {
    if (c == 0)
        throw new ArgumentException("Color is not set", "c");
    //...
}

Ответ 6

Точка, вероятно, состоит в том, что она имеет меньшее положительное целочисленное возможное значение.

Почему менее позитивно?

Чтобы иметь возможность правильно обрабатывать перечисление с операцией бит-сдвига.

Я, естественно, говорю о значении по умолчанию, которое может быть изменено разработчиком.

Ответ 7

Я не уверен, почему, но...

Вот документ о перечислении С#: http://msdn.microsoft.com/en-us/library/sbbt4032.aspx

Перечислители могут использовать инициализаторы для переопределения значений по умолчанию, как показано в следующем примере.

enum Days {Sat = 1, Sun, Mon, Tue, Wed, Thu, Fri};

В этом перечислении последовательность элементов вынуждена начинать с 1 вместо 0. Однако рекомендуется включить константу, которая имеет значение 0. Для получения дополнительной информации см. "Типы перечислений" (Руководство по программированию на С#).

Они рекомендуют всегда включать значение enum-заполнителя, соответствующее значению 0, иначе вы можете столкнуться с проблемами. Вы можете назвать это значение перечисления чем-то вроде Undefined или Default или что-то в этом роде.

Как я уже упоминал в своем комментарии к вашему вопросу, моя рекомендация заключалась бы в том, чтобы не использовать значения для ваших перечислений вообще, если у вас нет веских оснований для этого. Если вам нужно, следуйте Руководство по программированию MSDN для типов перечислений

Ответ 8

enum int (по умолчанию). Перечисления являются человекочитаемыми ints для нашего исходного кода, но когда ваша программа скомпилирована, нет enum, только int s. Значение по умолчанию для int равно 0.

Этот код:

public enum test { One, Two, Three }

var x = test.One;
var y = 0;

Становится это в IL:

IL_0001:  ldc.i4.0   
IL_0002:  stloc.0     
IL_0003:  ldc.i4.0    
IL_0004:  stloc.1 

Итак, как может int иметь значение по умолчанию 1 (по вашему усмотрению) в некоторых случаях, но не другие?