Получить интегральное значение в штучной упаковке Enum - PullRequest
4 голосов
/ 14 апреля 2009

Я решил, что невозможно выполнить следующие (эквивалентные) операции перечисления с помощью отражения - так как класс Enum не имеет операторов, и в выдаваемом коде нет операторов:

object boxedEnum = MyEnum.Flag1 | MyEnum.Flag2;
boxedEnum &= ~MyEnum.Flag2; // Remove the flag.

Итак, я сейчас делаю следующее (эквивалент):

int boxedEnumValue = (int) boxedEnum;
boxedEnumValue &= ~MyEnum.Flag2;
boxedEnum = Enum.ToObject(boxedEnum.GetType(), boxedEnumValue);

Что отлично работает, единственная проблема в том, что эквивалентный код для преобразования boxedEnum в целое число:

int boxedEnumValue = int.Parse(Enum.Format(boxedEnum.GetType(), boxedEnum, "X"), System.Globalization.NumberStyles.HexNumber);

С чем, я уверен, вы согласитесь, это ужасно и смешно.

Итак, у этого вопроса есть два аспекта. Было бы замечательно, если бы кто-то мог доказать, что я не прав, и предоставить средство для выполнения двоичных операций над перечисленными в штучной форме перечислениями - иначе будет полезен любой способ избежать обхода строки.

Гуффа дал мне то, что мне было нужно, чтобы преобразовать перечисление в определенный тип. Я создал метод расширения, который делает все возможное:

    /// <summary>
    /// Gets the integral value of an enum.
    /// </summary>
    /// <param name="value">The enum to get the integral value of.</param>
    /// <returns></returns>
    public static T ToIntegral<T>(this object value)
    {
        if(object.ReferenceEquals(value, null))
            throw new ArgumentNullException("value");
        Type rootType = value.GetType();
        if (!rootType.IsEnum)
            throw new ArgumentOutOfRangeException("value", "value must be a boxed enum.");
        Type t = Enum.GetUnderlyingType(rootType);

        switch (t.Name.ToUpperInvariant())
        {
            case "SBYTE":
                return (T)Convert.ChangeType((sbyte) value, typeof(T));
            case "BYTE":
                return (T) Convert.ChangeType((byte) value, typeof(T));
            case "INT16":
                return (T) Convert.ChangeType((Int16) value, typeof(T));
            case "UINT16":
                return (T) Convert.ChangeType((UInt16) value, typeof(T));
            case "INT32":
                return (T) Convert.ChangeType((Int32) value, typeof(T));
            case "UINT32":
                return (T) Convert.ChangeType((UInt32) value, typeof(T));
            case "INT64":
                return (T) Convert.ChangeType((Int64) value, typeof(T));
            case "UINT64":
                return (T) Convert.ChangeType((UInt64) value, typeof(T));
            default:
                throw new NotSupportedException();
        }
    }

Ответы [ 2 ]

6 голосов
/ 14 апреля 2009

Штучное значение никогда не может быть изменено на месте. Вам просто нужно распаковать enum, выполнить операцию и снова поставить ее в поле:

boxedEnum = (MyEnum)boxedEnum & ~MyEnum.Flag2;

Редактировать:

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

boxedEnum = (int)boxedEnum & ~2;

MyEnum value = (MyEnum)boxedEnum; // works both for a boxed int and a boxed MyEnum
0 голосов
/ 14 апреля 2009
int enumValue = (int)SomeEnum.Val1 | (int)SomeEnum.Val2;
SomeEnum e = (SomeEnum)enumValue;

Хотите ли вы чего-то добиться?

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