2009-04-14 8 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を有効にする同等のコードであるということです

私はあなたが同意すると確信していますが、ひどいとハッキーです。

この質問には2つのプロングがあります。誰かが私を間違っていると証明し、ボックス化された列挙型のバイナリ演算を実行する方法を提供することができればすばらしいでしょう。そうでなければ、文字列の往復を避ける方法があれば感謝します。

Guffaは、enumを特定のタイプに変換するために必要なものを教えてくれました。私は核心-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

ボックス化された値は決して変更できません。あなたは、列挙型をUnboxの操作を行うと、再びそれをボックスする必要があります。

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

編集:

提供列挙型の基になる型がintであることを、あなただけのint型と、それをボックスにしUnboxのことができますintに。ボックス化されたintは、後で列挙型にアンボックスすることができます:

boxedEnum = (int)boxedEnum & ~2; 

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

残念ながら私はできません。任意の種類の列挙型を受け入れる必要のあるヘルパーメソッドです。 –

+0

enumの基になる型がintの場合、intにボックスをunboxしintにboxすることができます。ボックス化されたintは、後で列挙型にunboxedすることができます。 – Guffa

+0

@Guffa you天才!私はそれを受け入れることができるようにあなたの答えを編集できますか? –

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

をあなたはこのような何かを達成したいですか?

+0

列挙型です。 intにキャストする前にunboxする必要があります。 –