1
\$\begingroup\$

Without any specific implementation details, how would you create a bitmask type that wraps binary arithmetic into something easy to read? Ideally, this would be used with an enum, which is why there are some generic methods.

Some Questions

  1. Is the type a struct or class?
  2. Is the type generic or are certain methods generic?
  3. Is it okay to constrain the generics to struct, IConvertible?
  4. Is a type like this preferred when working with bitmasks?

Starting Example: Here's a fiddle.

//Example Use
var days = new Bitmask((ulong)(Day.Monday | Day.Tuesday));
days.Contains((ulong)Day.Friday); //false
days.Contains((ulong)Day.Monday); //true
//Example Use END    

public enum Day { Monday = 1, Tuesday = 2, Wednesday = 4, Thursday = 8, Friday = 16, Saturday = 32, Sunday = 64 }

public struct Bitmask
{
    //Bitmask Value
    private ulong _value;
    public ulong Value 
    { 
        get { return _value; }
        set { _value = value; }
    }   

    //Constructor
    public Bitmask(ulong value) { _value = value; }


    //Methods
    public bool Any() { return _value != 0; }

    public void Clear() { _value = 0; }

    public bool Contains(ulong value) { return (_value & value) == value; } 

    public bool Equals(ulong value) { return _value == value; }

    public List<TEnum> ToList<TEnum>() where TEnum : struct, IConvertible
    {
        var local = this;
        var result = ((TEnum[])Enum.GetValues(typeof(TEnum))).Where(m => local.Contains<TEnum>(m)).ToList();
        return result;  
    }   
}
\$\endgroup\$
4
  • \$\begingroup\$ The implementation of Contains doesn't look right to me: new Bitmask(1).Contains(3) returns true. \$\endgroup\$
    – mjolka
    Oct 2, 2015 at 1:23
  • \$\begingroup\$ @mjolka Actually, new Bitmask(1).Contains(3) doesn't really make sense so I will add some code to clarify what the type is doing. Also, the fiddle provides some extra details. \$\endgroup\$ Oct 2, 2015 at 1:32
  • 2
    \$\begingroup\$ Enum provides the method HasFlag, much like your 'Contains'. \$\endgroup\$
    – hocho
    Oct 2, 2015 at 4:09
  • \$\begingroup\$ Don't add extra code as it invalidates answers. \$\endgroup\$
    – Quill
    Oct 6, 2015 at 23:13

1 Answer 1

7
\$\begingroup\$

It looks like you are misusing an enum as just a more cumbersome way to write a ulong.

If the days of the week are meant to be treated as a set rather than a single value (i.e., more like checkboxes than radio buttons), then you should be using the [Flags] attribute. In fact, this is almost exactly the example given in the MSDN documentation:

[Flags]
enum Days2
{
    None = 0x0,
    Sunday = 0x1,
    Monday = 0x2,
    Tuesday = 0x4,
    Wednesday = 0x8,
    Thursday = 0x10,
    Friday = 0x20,
    Saturday = 0x40
}

class MyClass
{
    Days2 meetingDays = Days2.Tuesday | Days2.Thursday;
}

Personally, I'd write the constants using left-shift operators:

[Flags]
enum Days2
{
    None = 0,
    Sunday = 1 << 0,
    Monday = 1 << 1,
    Tuesday = 1 << 2,
    Wednesday = 1 << 3,
    Thursday = 1 << 4,
    Friday = 1 << 5,
    Saturday = 1 << 6
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.