Сообщение Re: Подводные камни enum от 08.05.2019 5:10
Изменено 08.05.2019 6:41 Sinclair
Re: Подводные камни enum
Здравствуйте, varenikAA, Вы писали:
AA>В процессе работы заметил, что
AA>enum довольно "слабый" тип, который скорее является простым алиасом/набором констант для
AA>численных типов.
AA>Так, доступим есть тип
AA>
AA>тогда, если
AA>
AA>или
AA>
AA>Т.е. что первый код, что второй приводят к скрытой ошибке.
Пока непонятно, в чём именно ошибка.
AA>Таким образом, мы вынужденны всегда проверять значение через
AA>
AA>, что согласитесь неудобно.
Примерно также реализованы енумы в С/С++. На выбор реализации енумов в дотнет существенно повлияли соображения интероперабельности с неуправляемым кодом.
К примеру, Flags-енумы вполне легально включают значения, не сводимые ни к одному из членов перечисления.
Теоретически, можно было бы разделить енумы на два подкласса — flags и unique; но это скорее затруднит, чем облегчит, их использование. И весьма существенно увеличит стоимость реализации.
Например, CLR устроен так, что все value-типы инициализируются битовыми нулями. Но вы совершенно не обязаны включать значение 0 в перечисление:
Если лично вам очень нужен енум с более жёстким поведением, вы всегда можете его свелосипедить:
AA>В процессе работы заметил, что
AA>enum довольно "слабый" тип, который скорее является простым алиасом/набором констант для
AA>численных типов.
AA>Так, доступим есть тип
AA>
AA>enum Month
AA>{
AA> Jan = 1,
AA> Feb = 2
AA>}
AA>
AA>тогда, если
AA>
AA>var zero = default(Month); //=> 0
AA>
AA>или
AA>
AA>var m = (Month)10; //=> 10!!!
AA>var t = m.GetType(); //=> Month!!!
AA>
AA>Т.е. что первый код, что второй приводят к скрытой ошибке.
Пока непонятно, в чём именно ошибка.
AA>Таким образом, мы вынужденны всегда проверять значение через
AA>
Enum.IsDefined
AA>, что согласитесь неудобно.
Примерно также реализованы енумы в С/С++. На выбор реализации енумов в дотнет существенно повлияли соображения интероперабельности с неуправляемым кодом.
К примеру, Flags-енумы вполне легально включают значения, не сводимые ни к одному из членов перечисления.
Теоретически, можно было бы разделить енумы на два подкласса — flags и unique; но это скорее затруднит, чем облегчит, их использование. И весьма существенно увеличит стоимость реализации.
Например, CLR устроен так, что все value-типы инициализируются битовыми нулями. Но вы совершенно не обязаны включать значение 0 в перечисление:
public enum Fail {Correct = 1};
...
var fail = new Fail[1]; //Омг, что у меня в Fail[0]?
Если лично вам очень нужен енум с более жёстким поведением, вы всегда можете его свелосипедить:
public struct StrictEnum<E> where E: struct, Enum
{
private E _value;
public StrictEnum(E value) => _value ?
{
if(!= Enum.IsDefined(typeof(E), value))
throw new ArgumentException();
_value = value;
}
...
}
Re: Подводные камни enum
Здравствуйте, varenikAA, Вы писали:
AA>В процессе работы заметил, что
AA>enum довольно "слабый" тип, который скорее является простым алиасом/набором констант для
AA>численных типов.
AA>Так, доступим есть тип
AA>
AA>тогда, если
AA>
AA>или
AA>
AA>Т.е. что первый код, что второй приводят к скрытой ошибке.
Пока непонятно, в чём именно ошибка.
AA>Таким образом, мы вынужденны всегда проверять значение через
AA>
AA>, что согласитесь неудобно.
Примерно также реализованы енумы в С/С++. На выбор реализации енумов в дотнет существенно повлияли соображения интероперабельности с неуправляемым кодом.
К примеру, Flags-енумы вполне легально включают значения, не сводимые ни к одному из членов перечисления.
Теоретически, можно было бы разделить енумы на два подкласса — flags и unique; но это скорее затруднит, чем облегчит, их использование. И весьма существенно увеличит стоимость реализации.
Например, CLR устроен так, что все value-типы инициализируются битовыми нулями. Но вы совершенно не обязаны включать значение 0 в перечисление:
Если лично вам очень нужен енум с более жёстким поведением, вы всегда можете его свелосипедить:
AA>В процессе работы заметил, что
AA>enum довольно "слабый" тип, который скорее является простым алиасом/набором констант для
AA>численных типов.
AA>Так, доступим есть тип
AA>
AA>enum Month
AA>{
AA> Jan = 1,
AA> Feb = 2
AA>}
AA>
AA>тогда, если
AA>
AA>var zero = default(Month); //=> 0
AA>
AA>или
AA>
AA>var m = (Month)10; //=> 10!!!
AA>var t = m.GetType(); //=> Month!!!
AA>
AA>Т.е. что первый код, что второй приводят к скрытой ошибке.
Пока непонятно, в чём именно ошибка.
AA>Таким образом, мы вынужденны всегда проверять значение через
AA>
Enum.IsDefined
AA>, что согласитесь неудобно.
Примерно также реализованы енумы в С/С++. На выбор реализации енумов в дотнет существенно повлияли соображения интероперабельности с неуправляемым кодом.
К примеру, Flags-енумы вполне легально включают значения, не сводимые ни к одному из членов перечисления.
Теоретически, можно было бы разделить енумы на два подкласса — flags и unique; но это скорее затруднит, чем облегчит, их использование. И весьма существенно увеличит стоимость реализации.
Например, CLR устроен так, что все value-типы инициализируются битовыми нулями. Но вы совершенно не обязаны включать значение 0 в перечисление:
public enum Fail {Correct = 1};
...
var fail = new Fail[1]; //Омг, что у меня в Fail[0]?
Если лично вам очень нужен енум с более жёстким поведением, вы всегда можете его свелосипедить:
public struct StrictEnum<E> where E: struct, Enum
{
private E _value;
public StrictEnum(E value)
{
if(!= Enum.IsDefined(typeof(E), value))
throw new ArgumentException();
_value = value;
}
...
}