Pretty way to assign a single bit in a FlagsAttribute enum?

M

Marcel Müller

Is there a better way to assign a single bit than using if/else?

public MyClass
{ public MyFlags Flags { get; set; }
public bool Min
{ get { return (Flags & MyFlags.Min) != 0; }
set { if (value) Flags |= MyFlags.Min; else Flags &= ~MyFlags.Min; }
}
...
}

[Flags]
public enum MyFlags
{ Min = 1<<1,
Max = 1<<2
}

The Setter uses a conditional expression. In some other languages I
could write something like
Flags = Flags & MyFlags.Min | value * MyFlags.Min;
Can a bool be used for anything else but the boolean operators (&,|...)
and 'if'?


Marcel
 
B

bradbury9

Is there a better way to assign a single bit than using if/else?

public MyClass
{ public MyFlags Flags { get; set; }
   public bool Min
   { get { return (Flags & MyFlags.Min) != 0; }
     set { if (value) Flags |= MyFlags.Min; else Flags &= ~MyFlags.Min; }
   }
   ...

}

[Flags]
public enum MyFlags
{ Min = 1<<1,
   Max = 1<<2

}

The Setter uses a conditional expression. In some other languages I
could write something like
   Flags = Flags & MyFlags.Min | value * MyFlags.Min;
Can a bool be used for anything else but the boolean operators (&,|...)
and 'if'?

Marcel

If the asign command was the same in both cases you could use a
ternary operator.
int bufferSize = (filetype=="pdf")? 100000 : 1000;
Is similar to:
int bufferSize;
if(filetype=="pdf"){
bufferSize = 100000;
}else{
bufferSize = 1000;
}
but you type less code, so could be considered better ;-)
 
J

Jeff Johnson

Is there a better way to assign a single bit than using if/else?

Not really. In order to turn off a bit without disturbing others, you have
no choice other than to use & plus ~. There is no single operator that does
this.

If you're looking for code that hides this, though, you might want to look
at the BitArray class.
 
M

Marcel Müller

Also, your post provides a good example of why one should prioritize
correctness and clarity over clever aesthetics. Doing otherwise increases
the risk of incorrect implementation, as in the statement you showed here
(which should read "Flags& ~MyFlags.Min..." instead of what your post
had).

True. You see, i did not really do it this way.

That said, you can do this:

Flags = value ? Flags | MyFlags.Min : Flags& ~MyFlags.Min;

That's fine, and it is quite obvious.
I did not have the ternary if in mind because I had different assignment
operators.

Of course, with simple extension methods you could avoid having to
explicitly write any bit-twiddling code at all for each place the flags
enum is used. And I find abstraction much more aesthetically pleasing than
I do an effort to win an obfuscated coding contest. :)

I tried the extension approach first, but it did not work for several
reasons.
Firstly, the way a value type is passed to extension methods is
significantly different from the way it is passed to member functions.

static void AssignBit<T>(this T target, T bit, bool value)
{ if (value)
target |= bit;
else
target &= ~bit;
}

This will modify a local copy of target rather than target for value
types, and "this ref T target" is not supported.

Secondly, I cannot set a type constraint to System.Enum and in addition
I cannot set a type constraint on the FlaggsAttribute, that is required
for the bit operations to work.

So extension wont help, or did I miss something?


Marcel
 
A

Arne Vajhøj

Is there a better way to assign a single bit than using if/else?

public MyClass
{ public MyFlags Flags { get; set; }
public bool Min
{ get { return (Flags & MyFlags.Min) != 0; }
set { if (value) Flags |= MyFlags.Min; else Flags &= ~MyFlags.Min; }
}
...
}

[Flags]
public enum MyFlags
{ Min = 1<<1,
Max = 1<<2
}

The Setter uses a conditional expression. In some other languages I
could write something like
Flags = Flags & MyFlags.Min | value * MyFlags.Min;
Can a bool be used for anything else but the boolean operators (&,|...)
and 'if'?

The code can be written in a few different ways.

But I don't see the point.

If you want "primitive efficient low level code" then you
let the calling code do the bit manipulation directly.

Keep MyFlags but drop MyClass (or keep MyClass but drop
the properties if MyClass has other functionality than
just being a wrapper).

If you want "nice encapsulated high level code", then
you keep MyClass but change it to:
- have bool properties with bool fields backing
(automatic or explicit)
- have methods or a property to export and import
a MyFlags from/to the bool fields

Arne
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top