Зачем нам нужно вводить листинг enum в С#
У меня есть перечисление вроде:
public enum Test:int
{
A=1,
B=2
}
Итак, здесь я знаю, что мой enum - это тип int, но если я хочу сделать что-то вроде следующего:
int a = Test.A;
это не работает.
Если у меня есть класс вроде:
public class MyTest
{
public static int A =1;
}
Могу сказать,
int a = MyTest.A;
Здесь мне не нужно явно выделять A
в int.
Ответы
Ответ 1
С обновленным примером:
public class MyTest
{
public static int A =1;
}
И использование:
int a = MyTest.A;
Это не то, как выглядят перечисления. Enums больше похожи (комментарии - это места, где мы отличаемся от реального перечисления):
public struct MyTest /* Of course, this isn't correct, because we'll inherit from System.ValueType. An enum should inherit from System.Enum */
{
private int _value; /* Should be marked to be treated specially */
private MyTest(int value) /* Doesn't need to exist, since there some CLR fiddling */
{
_value = value;
}
public static explicit operator int(MyTest value) /* CLR provides conversions automatically */
{
return value._value;
}
public static explicit operator MyTest(int value) /* CLR provides conversions automatically */
{
return new MyTest(value);
}
public static readonly MyTest A = new MyTest(1); /* Should be const, not readonly, but we can't do a const of a custom type in C#. Also, is magically implicitly converted without calling a constructor */
public static readonly MyTest B = new MyTest(2); /* Ditto */
}
Да, вы можете легко получить "базовое" значение int, но значения A
и B
по-прежнему строго типизированы как тип MyTest
. Это гарантирует, что вы случайно не используете их в тех местах, где они не подходят.
Ответ 2
Итак, здесь я знаю, что мое перечисление - это тип int
Нет, нет. Он имеет базовый тип int
, но это отдельный тип. Черт, эта половина точки перечисления в первую очередь - что вы можете сохранить типы раздельными.
Если вы хотите конвертировать между значением перечисления и его числовым эквивалентом, вы бросаете - это не так больно, и он сохраняет ваш код более чистым с точки зрения безопасности типов. По сути, это одна из тех вещей, где редкость этого является правильной вещью, чтобы сделать ее явной.
EDIT: одна странность, о которой вам следует знать, заключается в том, что существует неявное преобразование из постоянного значения 0 в тип перечисления:
Test foo = 0;
Фактически, в реализации MS это может быть любая константа 0:
Test surprise = 0.0;
Это ошибка, но одна из которых слишком поздно исправить:)
Я считаю, что остальное для этого неявного преобразования заключалось в том, чтобы упростить проверку того, установлены ли какие-либо биты в перечислении флагов и другие сравнения, которые будут использовать "значение 0". Лично я не поклонник этого решения, но это стоит, по крайней мере, знать об этом.
Ответ 3
"Основной тип указывает, сколько хранилищ выделено для каждого перечислителя. Однако для преобразования из типа перечисления в интегральный тип требуется явный приведение" .
Ответ 4
Значения перечисления не относятся к типу int
. int
является базовым типом перечисления. Перечисления технически интегрированы, но логически (с точки зрения языка С#) нет. int
(System.Int32
) является базовым типом всех перечислений по умолчанию, если вы явно не указали другой.
Ответ 5
Вы перечисляете тип Test
. Это не int
только потому, что ваше перечисление имеет значения целых чисел.
Вы можете указать свой enum для получения значения int:
int a = (int) Test.A;