2012-02-13 136 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'?你確定你對這個以及其他所有溢出在「<< 32」之上都可以嗎? – Oded 2012-02-13 14:50:28

+0

是的,這是一個相當龐大的數字。即使使用'enum MyEnum:long',期待意想不到的過去64 – spender 2012-02-13 14:53:48

+0

當你說「壓縮字符串」時,你的字面意思是什麼System.String?或者你只是指組合的標誌值(作爲MyEnum與相應的位設置)?您已有的組合標誌值,您不需要轉換方法,只需將它們組合在一起即可。枚舉只是一個正常的整數與口紅上(這就是爲什麼不能有1 << 280,因爲它會溢出)。 – 2012-02-13 14:54:31

回答

2

enum值由內存中的整數字段支持。那麼你需要比整數本身更多的壓縮?

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

但要小心,因爲1 < < 280(2^280)是一個不能被存儲在Int32甚至Int64一個相當大的數字。

+2

更不用說,有了'Int32'的支持,這將溢出相當快...最大一個標誌枚舉的32個值。 – Oded 2012-02-13 15:02:51

+0

也許一個枚舉不是正確的解決方案,然後... – 2012-02-13 15:21:43

+0

@JimGeurts,可以肯定的是,使用枚舉最多可以存儲的數字是long.MaxValue。因此,根據您的具體要求,可能會有其他更適合的結構。 – 2012-02-13 15:23:33

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

這看起來像我在找什麼。謝謝! – 2012-02-13 19:44:39