This is a bit of a "soft question", but basically I'm trying to take this pattern that makes use of implicit conversion to byte:
byte x = 0;
x |= 2; // implicit conversion of "x | 2" to byte here
and use it for removing开发者_如何转开发 bits:
x &= ~2; // compile error
The shortest that I could come up with is this:
x &= unchecked((byte) ~2);
(at which point I start seriously considering just writing x &= 253; // ~2
instead... or just the good old explicit cast: x = (byte) (x & ~2);
)
Am I missing a shorter way?
How about this:
{
byte x = 0;
x |= 2;
x &= 0xFF & ~2;
}
Explanation: There are two issues here. First, the unary operator '~':
From C# Spec 4.1.5:
The integral-type unary and binary operators always operate with signed 32-bit precision, unsigned 32-bit precision, signed 64-bit precision, or unsigned 64-bit precision:
For the unary + and ~ operators, the operand is converted to type T, where T is the first of int, uint, long, and ulong that can fully represent all possible values of the operand. The operation is then performed using the precision of type T, and the type of the result is T.
Once you apply the unary operator, the result is always, at the smallest, an 'int' type. From there, you want to implicitly convert to a byte.
Secondly, Implicit conversions:
A constant expression of type int can be converted to sbyte, byte, short, ushort, uint, or ulong, provided the value of the constant expression is within the range of the destination type.
So, ~2, is always an int. It cannot be converted to byte implicitly, because its outside of the range. You can convert implicitly if you constrain it to be within the range.
You can name constant in this way:
[Flags]
enum SomeType : byte {
Value = 2,
}
public void Method () {
SomeType t = 0;
t |= SomeType.Value;
t &= ~SomeType.Value;
}
Use a custom type
public struct Bits
{
byte x;
public Bits(int x) { this.x = (byte)x; }
public Bits(byte x) { this.x = x; }
public Bits(Bits x) { this.x = x.x; }
public static implicit operator byte(Bits x) { return x.x; }
public static implicit operator Bits(byte x) { return new Bits(x); }
public static implicit operator Bits(int x) { return new Bits(x); }
}
static void Main(string[] args)
{
Bits x = 0;
x |= 2;
x &= ~2;
}
Additionally you can write en extension method for byte to set bits
public static byte Set(this byte x, byte v)
{
return (byte)(x | v);
}
public static byte Unset(this byte x, byte v)
{
return (byte)(x & ~v);
}
static void Main(string[] args)
{
byte x = 0;
x = x.Set(2);
x = x.Unset(2);
}
byte x = 6;
Console.WriteLine(x & ~(byte)2);
this works for me, prints 4
精彩评论