2012-02-13 8 views
0

私は以下のように定義される列挙型があります:私はと同様に、可能な限り短い文字列に使用を変換できるようにしたいと思い列挙型の値を圧縮された文字列に変換する方法は?

[Flags] 
public enum MyEnum 
{ 
    None = 0, 

    ValueOne    = 1 << 0, 
    ValueTwo    = 1 << 1, 
    ValueThree    = 1 << 2, 
    ValueFour    = 1 << 3, 
    ... 
    ValueTwoEightyOne   = 1 << 280, 
} 

var compressedString = ConvertToCompressedString(MyEnum.ValueOne | MyEnum.ValueThree | MyEnum.ValueFour); 

そしての別の部分でのこのプログラムは、私が戻って列挙にcompressedStringを変換したい

var enumValue = ConvertBack(compressedString); 

非常に多くの値を持つ列挙型を変換する効率的な方法は何ですか?このタイプのユースケースを処理するためのより良い方法がある場合は、私は興味があります。

+4

'ValueTwoEightyOne = 1 << 280'?あなたはこれでOKで、他のすべてのオーバーフローは '<< 32'ですか? – Oded

+0

ええ、それはかなりひどい数字です。 「enum MyEnum:long'」を使用しても、予期しない過去64日を期待してください。 – spender

+0

「圧縮された文字列」と言うと、文字通りSystem.Stringを意味しますか?または、結合されたフラグ値(それぞれのビットが設定されたMyEnum)を意味するだけですか?あなたがすでに持っているフラグ値を組み合わせれば、変換方法は必要ありません。列挙型は、通常の整数であり、その上に口紅が付いています(オーバーフローするので、1 << 280を持つことはできません)。 –

答えて

2

enum値は、メモリ内の整数フィールドによって保持されます。だから、整数そのものよりも何倍の圧縮が必要ですか?

MyEnum value = MyEnum.ValueOne | MyEnum.ValueThree | MyEnum.ValueFour; 
int i = (int)value; 
// transport i 

しかし、注意してください1 < < 280は、(2^280)Int32あるいはInt64に保存することができない、かなり多数あるため。

+2

バッキングの 'Int32'では、 flags列挙のための32の値。 – Oded

+0

おそらく列挙型はここの正しい解決策ではありません。 –

+0

@JimGeurts、確かにenumsで格納できる最大の数値はlong.MaxValueです。したがって、あなたの正確な要件に応じて、他のより適合した構造が存在するかもしれません。 –

1

フラグが64個以上ある「Flags enum」が必要な場合は、おそらくビットインデックスのみを使用し、その値を保持するクラス内にBitArrayをラップします。

コンパクトな表現を得るには、ビット配列をバイト配列に変換できます。コードからその手順を省略しましたが、たとえば次のようにすることができます。 like this(エンディアンに注意してください)

public class LargeFlagsEnum<T> where T : struct 
{ 
    private BitArray bits; 

    public LargeFlagsEnum(int numBits) 
    { 
     if (!(typeof(T).IsEnum)) 
     throw new ArgumentException("Expected enum type"); 
     bits = new BitArray(numBits); 
    } 

    public byte[] GetBytes() 
    { 
     return bits.ConvertToByteArray(); 
    } 

    public void Set(T flag, bool value) 
    { 
     bits[Convert.ToInt32(flag)] = value; 
    } 

    public bool Get(T flag) 
    { 
     return bits[Convert.ToInt32(flag)]; 
    }  
} 

// Example: 

enum MyFlags 
{ 
    First = 1, 
    SomethingElse = 280,  
} 

class Example 
{ 
    void Main() 
    { 
     var someFlags = new LargeFlagsEnum<MyFlags>(281); 
     someFlags.Set(MyFlags.SomethingElse, true); 
     Transmit(someFlags.GetBytes()); 
    } 
} 
+0

これは私が探しているようです。ありがとう! –

関連する問題