Как преобразовать значение перечисления в сжатую строку? - PullRequest
0 голосов
/ 13 февраля 2012

У меня есть перечисление, которое определяется как:

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

И затемв другой части программы я хотел бы преобразовать сжатую строку обратно в перечисление

var enumValue = ConvertBack(compressedString);

Каков эффективный метод преобразования перечисления с таким количеством значений?Если есть лучший способ работы с этим типом сценария использования, я заинтересован.

Ответы [ 2 ]

2 голосов
/ 13 февраля 2012

enum значения поддерживаются целочисленным полем в памяти.Так какое же сжатие вам нужно, чем само целое число?

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

Но будьте осторожны, потому что 1 << 280 (2 ^ 280) - это довольно большое число, которое не может быть сохранено в <code>Int32 или даже Int64.

1 голос
/ 13 февраля 2012

Если бы мне потребовалось перечисление Flags с более чем 64 флагами, я бы, вероятно, использовал перечисление только для битовых индексов, а затем обернул бы BitArray внутри класса для хранения значений.

Дляполучить компактное представление, вы можете преобразовать битовый массив в байтовый массив.Я пропустил этот шаг в коде, но вы можете сделать, например, вот так (обратите внимание на порядок байтов!)

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()); 
   }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...