代码之家  ›  专栏  ›  技术社区  ›  Jonathan C Dickinson

获取装箱枚举的整数值

  •  4
  • Jonathan C Dickinson  · 技术社区  · 15 年前

    我已经决定不可能通过反射执行以下(等效)枚举操作-因为枚举类没有运算符,并且发出的代码也没有公开任何运算符:

    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);
    

    这很好,唯一的问题是,将boxenum转换为整数的等效代码是:

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

    我相信你会同意,这是可怕的和下流的。

    所以这个问题有两个方面。如果有人能证明我是错的,并提供一种对装箱的枚举执行二进制操作的方法,那就太棒了,否则任何避免字符串往返的方法都会受到赞赏。

    Guffa 给出了将枚举转换为特定类型所需的内容。我编写了一个扩展方法,它可以完成以下任务:

        /// <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 回复  |  直到 15 年前
        1
  •  6
  •   Guffa    15 年前

    装箱值永远不能就地更改。您只需取消对枚举的绑定,执行操作并再次对其进行装箱:

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

    编辑:

    如果枚举的基础类型为int,则只需将其取消绑定到int并将其装箱到int。装箱的int稍后可以取消绑定到枚举类型:

    boxedEnum = (int)boxedEnum & ~2;
    
    MyEnum value = (MyEnum)boxedEnum; // works both for a boxed int and a boxed MyEnum
    
        2
  •  0
  •   Kirtan    15 年前
    int enumValue = (int)SomeEnum.Val1 | (int)SomeEnum.Val2;
    SomeEnum e = (SomeEnum)enumValue;
    

    你想实现这样的目标吗?