Те, кто знает на память книгу Дж.Рихтера C# via .NET, в этом врядли найдут для себя что-то новое/интересное.
 

 Всё началось с того, что было у меня два похожих enum'ов (к примеру Numbers и BigNumbers) и нужно было как-то переменные первого типа приводить к другом, и наоборот. 

enum Numbers
    {
        One,
        Two,
        Three
    }

    enum BigNumbers
    {
        One,
        Two,
        Three,
        Four,
        Five
    }

На практике такие преобразования выглядят примерно так :

Numbers n1 = Numbers.One;
Numbers n2 = (Numbers) 2;
Int32 i1 = (Int32) n1;

BigNumbers b1 = BigNumbers.Five;

Numbers n3 = (Numbers) b1;

Console.WriteLine(String.Format("n1 = {0}", n1));
Console.WriteLine(String.Format("n2 = {0}", n2));
Console.WriteLine(String.Format("i1 = {0}", i1));
Console.WriteLine(String.Format("b1 = {0}", b1));
Console.WriteLine(String.Format("n3 = {0}", n3));
 

В результате на экране мы получим следующее:

n1 = One
n2 = Three
i1 = 0
b1 = Five
n3 = 4 

  Здесь мы видим, что n3 теперь равняется 4-м. Логичный, но не совсем ожидаемый для меня результат. В таком случае хотелось бы получить какой-то Exception.

 Теперь разберёмся что представляет собой enum и почему он так работает.

Enum (перечесляемый тим, enumerated type) предоставляет нам возможность хранить пару имя-значение и пришли в дополнение к константом (например: вместо того, чтоб в методе возвращать код ошибки, можно создать enum с именами ошибок).  По сути, System.Enum представляет обёкт размерного (value) типа, пронаследованного от System.ValueType:

 public abstract class Enum : ValueType, IComparable, IFormattable, IConvertible


И, по умолчию, запись  "enum Numbers" соответствует "enum Numbers : int". В этом можно убедится, посмотрев на наше приложение с помощью IL DASM, который входит в комплект поставки .NET Framework SDK.

.class private auto ansi sealed Enums.Numbers       extends [mscorlib]System.Enum{} // end of class Enums.Numbers
.field public static literal valuetype Enums.Numbers One = int32(0x00000000)

 
Таким образом мы видим, что все элементы нашего enum являются целыми числами (int). Вместо int, можно указать byte, sbyte, short, ushort, int, long, и ulong. Интересно что если указать имя типа так, как они именуются в FCL (Byte, Int32 и т.д.), то мы получим ошибку: 
 Type byte, sbyte, short, ushort, int, uint, long, or ulong expected
 
 
Вернёмся к нашему примеру. Чтоб в нём всё работало так, как ожидалось, достаточно добавить такой код:

 if (!Enum.IsDefined(typeof(Numbers), b1)){throw new ArgumentException();}

 

Enums.zip (3.01 kb)


Comments

Michael M. Ukraine

Wednesday, July 22, 2009 11:55 PM

Michael M.

И в правду, ничего интересного.
Но всё равно полезно(проверить знание и заполнить пробелы) Wink

GrammarNazi Russia

Friday, August 20, 2010 2:00 PM

GrammarNazi

видИм!

e0ne United States

Monday, August 23, 2010 11:57 PM

e0ne

Спасибо, исправил.

Comments are closed