Change from bitarray to enum
Asked Answered
B

4

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) // https://mcmap.net/q/366432/-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?

Betseybetsy answered 17/4, 2016 at 9:24 Comment(0)
P
2

just simply cast it to byte!.
example:

byte eventMessages =(byte)( EventMessageTypes.aaa | EventMessageTypes.bbb | EventMessageTypes.ccc);
Philanthropist answered 17/4, 2016 at 10:12 Comment(3)
Hmm... Severity Code Description Project File Line Error CS0019 Operator '|' cannot be applied to operands of type 'byte' and 'EventMessageTypes'Betseybetsy
@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.Philanthropist
@David Wallis I'm glad I could help.Philanthropist
V
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

Votyak answered 17/4, 2016 at 9:35 Comment(0)
P
2

just simply cast it to byte!.
example:

byte eventMessages =(byte)( EventMessageTypes.aaa | EventMessageTypes.bbb | EventMessageTypes.ccc);
Philanthropist answered 17/4, 2016 at 10:12 Comment(3)
Hmm... Severity Code Description Project File Line Error CS0019 Operator '|' cannot be applied to operands of type 'byte' and 'EventMessageTypes'Betseybetsy
@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.Philanthropist
@David Wallis I'm glad I could help.Philanthropist
M
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
{
   ...
}
Margretmargreta answered 17/4, 2016 at 10:29 Comment(1)
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. :)Betseybetsy
U
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>();

Unijugate answered 17/4, 2016 at 9:28 Comment(3)
I dont want to use the bit array, - that's what I want to swap for the enum and then the values with the bitwise or.Betseybetsy
well then, how do you get/generate the data? as bools/bits or bytesSettlement
you can convert int to enum by (enum)int/byte and the other way around (int/byte)enumSettlement

© 2022 - 2024 — McMap. All rights reserved.