Являются ли типы перечисления .NET действительно изменяемыми типами значений?

Глядя с отражением на поля типа enum, я с удивлением заметил, что поле «backing instance», которое содержит фактическое значение определенного экземпляра enum, не являетсяprivateкак я бы подумал, ноpublic, И это не былоreadonly или. (IsPublic правда,IsInitOnly ложный.)

Многие люди считают «изменяемые» типы значений в системе типов .NET «злыми», поэтомупочему типы enum (например, созданный из кода C #)только то?

Теперь, как выясняется, у компилятора C # есть какая-то магия, которая отрицает существование открытого поля экземпляра (но см. Ниже), но, например, PowerShell вы можете сделать это:

prompt> $d = [DayOfWeek]::Thursday
prompt> $d
Thursday
prompt> $d.value__ = 6
prompt> $d
Saturday

Полеvalue__ может быть написано

Теперь, чтобы сделать это в C #, мне пришлось использоватьdynamic потому что кажется, что с нормальной привязкой члена во время компиляции, C # делает вид, чтоpublic Поле экземпляра не существует. Конечно использоватьdynamicнам придется использоватьзаниматься боксом перечислимого значения.

Вот пример кода на C #:

// create a single box for all of this example
Enum box = DayOfWeek.Thursday;

// add box to a hash set
var hs = new HashSet<Enum> { box, };

// make a dynamic reference to the same box
dynamic boxDyn = box;

// see and modify the public instance field
Console.WriteLine(boxDyn.value__);  // 4
boxDyn.value__ = 6;
Console.WriteLine(boxDyn.value__);  // 6 now

// write out box
Console.WriteLine(box);  // Saturday, not Thursday

// see if box can be found inside our hash set
Console.WriteLine(hs.Contains(box));  // False

// we know box is in there
Console.WriteLine(object.ReferenceEquals(hs.Single(), box));  // True

Я думаю, что комментарии говорят сами за себя. Мы можем изменить экземпляр типа enumDayOfWeek (может быть любого типа enum из сборки BCL или из сборки "home-made") черезpublic поле. Поскольку экземпляр находился в хеш-таблице, а мутация приводила к изменению хеш-кода, экземпляр находится в неправильном «корзине» после мутации, иHashSet<> не может функционировать.

Почему разработчики .NET решили сделать поле экземпляра перечислимых типовpublic?

Ответы на вопрос(1)

Ваш ответ на вопрос