2009-04-14 85 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