Здравствуйте, varenikAA, Вы писали:
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;
}
...
}