2009-04-14 61 views
4

我已经决定了它不可能通过反射做以下(相当于)枚举操作 - 如枚举类没有运营商,并且也不会发出代码暴露任何运营商:获取盒装枚举的积分值

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

我相信你会同意的是可怕和黑客。

所以这个问题有两个问题。如果有人能证明我错了,并提供了对盒装枚举执行二进制操作的方法 - 否则任何避免字符串往返的方法都将不胜感激。

Guffa给了我所需要的,以便将枚举转换为特定类型。我创作的,做一些本质gritties扩展方法:

/// <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(); 
     } 
    } 

回答

6

盒装值永远不能改变。你只需要拆箱枚举,做了手术,并再次盒吧:

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

编辑:

前提是基础类型的枚举类型为int,你可以拆箱它为int和框它整数盒装int可以在以后取消装箱到枚举类型:

boxedEnum = (int)boxedEnum & ~2; 

MyEnum value = (MyEnum)boxedEnum; // works both for a boxed int and a boxed MyEnum 
+0

不幸的是我不能。它是一种帮助方法,需要接受任何种类的枚举。 – 2009-04-14 09:57:54

0
int enumValue = (int)SomeEnum.Val1 | (int)SomeEnum.Val2; 
SomeEnum e = (SomeEnum)enumValue; 

你想达到这样的事?

+0

枚举被装箱。在投射到一个int之前,你必须解开它。 – 2009-04-14 09:56:38