6

I currently have some crude google code.. that works but I want to swap to an enum.

Currently I need a byte to represent some bit flags that are set,

I currently have this:

 BitArray bitArray =new BitArray(new bool[] { true, true, false, false, false, false, false, false });

used in line..

new byte[] {ConvertToByte(bitArray)})

with ConvertToByte from this site...

    private static byte ConvertToByte(BitArray bits) // http://stackoverflow.com/questions/560123/convert-from-bitarray-to-byte
    {
        if (bits.Count != 8)
        {
            throw new ArgumentException("incorrect number of bits");
        }
        byte[] bytes = new byte[1];
        bits.CopyTo(bytes, 0);
        return bytes[0];
    }

However I wanted to use an enum as I touched on, so I created it as so:

[Flags]
public enum EventMessageTypes
{
    None = 0,
    aaa = 1, 
    bbb = 2, 
    ccc = 4, 
    ddd = 8, 
    eee = 16,
    fff = 32,   
    All = aaa | bbb | ccc | ddd | eee | fff // All Events
}

and then

        // Do bitwise OR to combine the values we want
        EventMessageTypes eventMessages = EventMessageTypes.aaa | EventMessageTypes.bbb | EventMessageTypes.ccc;

But how do I then get eventMessages to a byte (0x07) I think! so I can append that to my byte array?

David Wallis
  • 185
  • 11

4 Answers4

2

Here's one way:

var bitArray = new BitArray(
    new [] { true, true, false, false, false, false, false, false });
var eventMessages = (EventMessageTypes)bitArray
    .Cast<Boolean>()
    .Reverse()
    .Aggregate(0, (agg, b) => (agg << 1) + (b ? 1 : 0));

Download for LinqPad

codekaizen
  • 26,990
  • 7
  • 84
  • 140
2

just simply cast it to byte!.
example:

byte eventMessages =(byte)( EventMessageTypes.aaa | EventMessageTypes.bbb | EventMessageTypes.ccc);
harold
  • 61,398
  • 6
  • 86
  • 164
mehrdad safa
  • 1,081
  • 9
  • 10
  • Hmm... Severity Code Description Project File Line Error CS0019 Operator '|' cannot be applied to operands of type 'byte' and 'EventMessageTypes' – David Wallis Apr 17 '16 at 13:07
  • 1
    @David Wallis pay attention to parenthesis please and try again. close all (|) operands to parenthesis and cast all to byte as one statement. for example this statement might be an error: `(byte)enum.value1|enum.value2;` because just value1 casted to byte. insert your code if still getting error. – mehrdad safa Apr 17 '16 at 13:17
  • @David Wallis I'm glad I could help. – mehrdad safa Apr 17 '16 at 15:27
2

You have a way of getting a byte, so now just cast:

byte b = ConvertToByte(bitArray);
EventMessageTypes a = (EventMessageTypes) b;

Also, a tip, restrict the enum range to byte to prevent someone later adding out of range values to the enum:

[Flags]
public enum EventMessageTypes : byte
{
   ...
}
weston
  • 54,145
  • 21
  • 145
  • 203
  • duh.. why didn't I think of that.. will try the restricting the range too.. Will have to wait until later and will post results. :) – David Wallis Apr 17 '16 at 13:03
1

If I understand your problem right, then in essence you can cast to enum like this EventMessageTypes result = (EventMessageTypes)ConvertToByte(bitArray);

BitArray bitArray = new BitArray(new bool[] 
    { true, true, false, false, 
      false, false, false, false });
EventMessageTypes b = (EventMessageTypes)ConvertToByte(bitArray);

you could for readability and future code reuse make a extension class

static class Extension
{
    public static byte ToByte(this BitArray bits)
    {
        if (bits.Count != 8)
        {
            throw new ArgumentException("incorrect number of bits");
        }
        byte[] bytes = new byte[1];
        bits.CopyTo(bytes, 0);
        return bytes[0];
    }

    static class EnumConverter<TEnum> where TEnum : struct, IConvertible
    {
        public static readonly Func<long, TEnum> Convert = GenerateConverter();

        static Func<long, TEnum> GenerateConverter()
        {
            var parameter = Expression.Parameter(typeof(long));
            var dynamicMethod = Expression.Lambda<Func<long, TEnum>>(
                Expression.Convert(parameter, typeof(TEnum)),
                parameter);
            return dynamicMethod.Compile();
        }
    }
    public static T ToEnum<T>(this byte b) where T : struct, IConvertible
    {
        if (!typeof(T).IsEnum)
        {
            throw new ArgumentException("T must be an enumerated type");
        }
        return EnumConverter<T>.Convert(b);
    }
}

Then you can write the convert like this. bitArray.ToByte() or even better like this EventMessageTypes b = bitArray.ToByte().ToEnum<EventMessageTypes>();

Thomas Andreè Wang
  • 3,379
  • 6
  • 37
  • 53