Возможность назначить недопустимое значение Enum через отражение - PullRequest
1 голос
/ 25 ноября 2010

Я только что столкнулся с каким-то странным поведением при установке значения перечисления с помощью отражения.Кажется, что я могу установить недопустимое значение для перечисления:

class EnumReflector
{
    public enum MyEnum
    {
        Option1 = 0,
        Option2,
        Option3
    }

    public MyEnum TheEnum { get; set; }

    public void Test()
    {
        PropertyInfo pi = this.GetType().GetProperty("TheEnum");
        string badValue = "1234";
        object propertyValue = Enum.Parse(pi.PropertyType, badValue, true);

        pi.SetValue(this, propertyValue, null);
    }
}

Теперь, если я вызову это:

        EnumReflector e = new EnumReflector();
        e.Test();
        if (e.TheEnum == EnumReflector.MyEnum.Option1 ||
            e.TheEnum == EnumReflector.MyEnum.Option2 ||
            e.TheEnum == EnumReflector.MyEnum.Option3)
        {
            Console.WriteLine("Value is valid");
        }
        else
        {
            Console.WriteLine("Value is invalid: {0} ({1})", e.TheEnum.ToString(), (int)e.TheEnum);
        }

Вывод:

Недопустимое значение: 1234 (1234)

Как это может быть?Я считаю, что одной из сущностей перечислений является их ограниченный набор значений!

Ответы [ 3 ]

5 голосов
/ 25 ноября 2010

Перечисления - это просто целые числа (любого целочисленного типа примитива, который может быть указан) с некоторыми определенными именованными константами. Для отражения нет необходимости назначать значение, которое не имеет именованной константы:

enum MyEnum {
    None, One, Two
}

MyEnum e = (MyEnum)100;

Компилируется и работает просто отлично. Обратите внимание, что это также является причиной статического метода Enum.IsDefined(), который проверяет, является ли значение перечисления определенным значением.

0 голосов
/ 25 ноября 2010

Вам даже не нужно прибегать к размышлению:

EnumReflector e = new EnumReflector();

e.TheEnum = (EnumReflector.MyEnum)1234;

if (e.TheEnum == EnumReflector.MyEnum.Option1 ||
    e.TheEnum == EnumReflector.MyEnum.Option2 ||
    e.TheEnum == EnumReflector.MyEnum.Option3)
{
    Console.WriteLine("Value is valid");
}
else
{
    Console.WriteLine("Value is invalid: {0} ({1})",
                      e.TheEnum.ToString(), (int)e.TheEnum);
}
0 голосов
/ 25 ноября 2010

Перечисления действительно ограничены значениями, но во время компиляции.Вот недостаток отражения: вы теряете все проверки во время компиляции, предоставляемые компилятором, и используете значения для своей ответственности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...