Comparing enum flags in C# - c#

I need to detect if a flag is set within an enum value, which type is marked with the Flag attribute.
Usually it is made like that:
(value & flag) == flag
But since I need to do this by generic (sometimes at runtime I event have only an "Enum" reference. I can not find an easy way to use the & operator. At the moment I make it like this:
public static bool IsSet<T>(this T value, T flags) where T : Enum
{
Type numberType = Enum.GetUnderlyingType(typeof(T));
if (numberType.Equals(typeof(int)))
{
return BoxUnbox<int>(value, flags, (a, b) => (a & b) == b);
}
else if (numberType.Equals(typeof(sbyte)))
{
return BoxUnbox<sbyte>(value, flags, (a, b) => (a & b) == b);
}
else if (numberType.Equals(typeof(byte)))
{
return BoxUnbox<byte>(value, flags, (a, b) => (a & b) == b);
}
else if (numberType.Equals(typeof(short)))
{
return BoxUnbox<short>(value, flags, (a, b) => (a & b) == b);
}
else if (numberType.Equals(typeof(ushort)))
{
return BoxUnbox<ushort>(value, flags, (a, b) => (a & b) == b);
}
else if (numberType.Equals(typeof(uint)))
{
return BoxUnbox<uint>(value, flags, (a, b) => (a & b) == b);
}
else if (numberType.Equals(typeof(long)))
{
return BoxUnbox<long>(value, flags, (a, b) => (a & b) == b);
}
else if (numberType.Equals(typeof(ulong)))
{
return BoxUnbox<ulong>(value, flags, (a, b) => (a & b) == b);
}
else if (numberType.Equals(typeof(char)))
{
return BoxUnbox<char>(value, flags, (a, b) => (a & b) == b);
}
else
{
throw new ArgumentException("Unknown enum underlying type " + numberType.Name + ".");
}
}
private static bool BoxUnbox<T>(object value, object flags, Func<T, T, bool> op)
{
return op((T)value, (T)flags);
}
But I don't like the never ending if - else blocks, so is there a way to cast these values that I can use the & operator or any other solution to check this?

For me it looks overcomplicated. How about this (keeping in mind that enum is always mapped to an integer value type):
public static bool IsSet<T>(T value, T flags) where T : struct
{
// You can add enum type checking to be perfectly sure that T is enum, this have some cost however
// if (!typeof(T).IsEnum)
// throw new ArgumentException();
long longFlags = Convert.ToInt64(flags);
return (Convert.ToInt64(value) & longFlags) == longFlags;
}

I wrote a set of extension methods for enums, in case you need it :
public static class EnumExtensions
{
private static void CheckEnumWithFlags<T>()
{
if (!typeof(T).IsEnum)
throw new ArgumentException(string.Format("Type '{0}' is not an enum", typeof(T).FullName));
if (!Attribute.IsDefined(typeof(T), typeof(FlagsAttribute)))
throw new ArgumentException(string.Format("Type '{0}' doesn't have the 'Flags' attribute", typeof(T).FullName));
}
public static bool IsFlagSet<T>(this T value, T flag) where T : struct
{
CheckEnumWithFlags<T>();
long lValue = Convert.ToInt64(value);
long lFlag = Convert.ToInt64(flag);
return (lValue & lFlag) != 0;
}
public static IEnumerable<T> GetFlags<T>(this T value) where T : struct
{
CheckEnumWithFlags<T>();
foreach (T flag in Enum.GetValues(typeof(T)).Cast<T>())
{
if (value.IsFlagSet(flag))
yield return flag;
}
}
public static T SetFlags<T>(this T value, T flags, bool on) where T : struct
{
CheckEnumWithFlags<T>();
long lValue = Convert.ToInt64(value);
long lFlag = Convert.ToInt64(flags);
if (on)
{
lValue |= lFlag;
}
else
{
lValue &= (~lFlag);
}
return (T)Enum.ToObject(typeof(T), lValue);
}
public static T SetFlags<T>(this T value, T flags) where T : struct
{
return value.SetFlags(flags, true);
}
public static T ClearFlags<T>(this T value, T flags) where T : struct
{
return value.SetFlags(flags, false);
}
public static T CombineFlags<T>(this IEnumerable<T> flags) where T : struct
{
CheckEnumWithFlags<T>();
long lValue = 0;
foreach (T flag in flags)
{
long lFlag = Convert.ToInt64(flag);
lValue |= lFlag;
}
return (T)Enum.ToObject(typeof(T), lValue);
}
}
The main drawback is that you can't specify where T : Enum : it is explicitly forbidden ("Constraint cannot be special class 'System.Enum'"), so the extension methods will appear in intellisense for all structs... I added the CheckEnumWithFlags method to check that the type is actually an enum, and has the Flags attribute.
UPDATE : Jon Skeet recently started an interesting library called UnconstrainedMelody which does exactly the same sort of things, and works around the generic type constraint limitation mentioned above

This should do the job for enum types with any underlying types:
public static bool IsSet<T>(this T value, T flags) where T : struct
{
return (Convert.ToInt64(value) & Convert.ToInt64(flags)) ==
Convert.ToInt64(flags);
}
Convert.ToInt64 is used because a 64-bit integer is the "widest" integral type possible, to which all enum values can be cast (even ulong). Note that char is not a valid underlying type. It seems that it is not valid in C#, but it is in general valid in CIL/for the CLR.
Also, you can't enforce a generic type constraint for enums (i.e. where T : struct); the best you can do is use where T : struct to enforce T to be a value type, and then optionally perform a dynamic check to ensure that T is an enum type.
For completeness, here is my very brief test harness:
static class Program
{
static void Main(string[] args)
{
Debug.Assert(Foo.abc.IsSet(Foo.abc));
Debug.Assert(Bar.def.IsSet(Bar.def));
Debug.Assert(Baz.ghi.IsSet(Baz.ghi));
}
enum Foo : int
{
abc = 1,
def = 10,
ghi = 100
}
enum Bar : sbyte
{
abc = 1,
def = 10,
ghi = 100
}
enum Baz : ulong
{
abc = 1,
def = 10,
ghi = 100
}
}

Personally, I think that look fine because you've wrapped it into a single purpose function. If you had that code scattered through an entire program I think you would have some problems, but what you've created improves clarity everywhere it is used and the function itself is clear enough what it does.
Just my opinion of course.
You could though, use the is keyword, which might help a little
public static bool IsSet<T>(this T value, T flags) where T : Enum
{
if (value is int)
{
return ((int)(object)a & (int)(object)b) == (int)(object)b);
}
//etc...

Simply use the Enum.HasFlag() Method !

I have used this to compare flags
public static bool IsSet<T>(this T input, T match)
{
return (Convert.ToUInt32(input) & Convert.ToUInt32(match)) != 0;
}
Here you can do the different conversions. From int to short to long.

or...
public static bool IsSet(this Enum value, Enum compare)
{
int baseValue = value.ToInt32();
int compareValue = compare.ToInt32();
if (baseValue == 0)
return false;
return ((baseValue & compareValue) == compareValue);
}

Related

Min and Max operations on enum values

Using C#, how can I take the min or max of two enum values?
For example, if I have
enum Permissions
{
None,
Read,
Write,
Full
}
is there a method that lets me do Helper.Max(Permissions.Read, Permissions.Full) and get Permissions.Full, for example?
Enums implement IComparable so you can use:
public static T Min<T>(T a, T b) where T : IComparable
{
return a.CompareTo(b) <= 0 ? a : b;
}
Since enums are convertible to integer types, you can just do:
var permissions1 = Permissions.None;
var permissions2 = Permissions.Full;
var maxPermission = (Permissions) Math.Max((int) permissions1, (int) permissions2);
Note that this could cause issues if your enum is based on an unsigned type, or a type longer than 32 bits (i.e., long or ulong), but in that case you can just change the type you are casting the enums as to match the type declared in your enum.
I.e., for an enum declared as:
enum Permissions : ulong
{
None,
Read,
Write,
Full
}
You would use:
var permissions1 = Permissions.None;
var permissions2 = Permissions.Full;
var maxPermission = (Permissions) Math.Max((ulong) permissions1, (ulong) permissions2);
can be called with 2 or more parameters
public static T GetMaxEnum<T>(params T[] enums) where T : struct, IConvertible
{
if (enums.Length < 2)
{
throw new InvalidEnumArgumentException();
}
return enums.Max();
}
This is what I came up with because I couldn't find anything in .NET that did this.
public static class EnumHelper
{
public static T Min<T>(T a, T b)
{
return (dynamic)a < (dynamic)b ? a : b;
}
public static T Max<T>(T a, T b)
{
return (dynamic)a > (dynamic)b ? a : b;
}
}
While this question is quite old, it shows up at the top for some searches I did, so here we go, with a little more detail than the existing answer:
Permissions p1 = Permissions.Read;
Permissions p2 = Permissions.Write;
var pMax = (Permissions)Math.Max( (int)p1, (int)p2 );
Alternatively in case the enum is long based:
var pMax = (Permissions)Math.Max( (long)p1, (long)p2 );
Why does this work?
enum values can be cast to int (or 'long'), which represents their position
An int can be cast back to an enum
Math.Max() apparently works on int
Sidenotes:
Appearently this also works for the mininum with Math.Min()
IEnumerable.Max() and IEnumerable.Min() can be used if you need the maximum or minimum of more than two enum values (if you don't mind System.Linq).
I think you want something like this:
public enum Enum1
{
A_VALUE,
B_VALUE,
C_VALUE
}
public enum Enum2
{
VALUE_1,
VALUE_2,
VALUE_3
}
class Program
{
static void Main(string[] args)
{
Program p = new Program();
Console.WriteLine(p.EnumMin<Enum1>());
Console.WriteLine(p.EnumMax<Enum2>());
}
T EnumMin<T>()
{
T ret; ;
Array x = Enum.GetValues(typeof(T));
ret = (T) x.GetValue(0);
return ret;
}
T EnumMax<T>()
{
T ret; ;
Array x = Enum.GetValues(typeof(T));
ret = (T)x.GetValue(x.Length-1);
return ret;
}
}
There is a one-stop means for getting the min and max for any enumeration. All it assumes is that the representation type is an int.
public Tuple<int,int> GetMinMaxOfEnumeration<T>()
{
if (!typeof (T).IsEnum)
{
throw new ArgumentException("Type must be an enumeration");
}
var valuesAsInt = Enum.GetValues(typeof (T)).Cast<int>().OrderBy(n => n).ToArray();
return new Tuple<int, int>(valuesAsInt.First(), valuesAsInt.Last());
}

How many overrides do you REALLY need in a struct in C#?

I am making a wrapper for a "word" in an emulator project. Its meant to put all my cast conversions all in one spot. I was just about to start implement all the overrides for math functions (+,-,/,8, shift, etc.) When it occured to me that shouldn't all the implicit's take care of that? Do I need to over ride >= and <= when I got > < and ==?
I thought I would ask this as while there are plenty of questions relating to how to create them, there aren't many on how much is enough. Here is the code below:
public struct word_t
{
ulong val;
word_t(ulong val) { this.val = val; }
public static implicit operator word_t(int a) { return new word_t((ulong)a); }
public static implicit operator word_t(long a) { return new word_t((ulong)a); }
public static implicit operator word_t(uint a) { return new word_t((ulong)a); }
public static implicit operator word_t(ulong a) { return new word_t((ulong)a); }
public static implicit operator int(word_t a) { return (int)a.val; }
public static implicit operator long(word_t a) { return (long)a.val; }
public static implicit operator uint(word_t a) { return (uint)a.val; }
public static implicit operator ulong(word_t a) { return (ulong)a.val; }
public static bool operator ==(word_t a, word_t b) { return a.val == b.val; }
public static bool operator !=(word_t a, word_t b) { return a.val != b.val; }
public static bool operator >(word_t a, word_t b) { return a.val > b.val; }
public static bool operator <(word_t a, word_t b) { return a.val < b.val; }
public override bool Equals(object obj) {
return obj.Equals(val);
}
public override int GetHashCode() {
return val.GetHashCode();
}
public override string toString() {
return val.ToString();
}
}
My gut tells me to "Trust the compiler" but my head always worries on how efficient it is.
PS I just realized I should override shifts because of the bit shifting of negative number problems, but for right now just imagine shifts just magically work like adds between uint and int.
I recommend this MSDN article: http://msdn.microsoft.com/en-us/library/8edha89s(v=VS.100).aspx
It shows the operators you can overload and any catches. You can overload <= and >= but they must be overloaded in pairs, as is true with == and != as well.
The complex match operators +=, etc are available if +, etc. is overloaded, etc.
>= and <=, however, are separate. That is, overloading > and == does not give you a >= operator implicitly.

C#: Inherit from Boolean?

(how) can I Inherit from Boolean?
(Or make my class comparable to Boolean with '=' Operator)
class MyClass : Boolean
{
public MyClass()
{
this = true;
}
}
class Program
{
public Program()
{
MyClass myClass = new MyClass();
if(myClass == true)
//do something...
else
//do something else...
}
}
You can't. System.Boolean is a struct, and you can't derive from structs.
Now, why do you want to do so, exactly? What's the bigger purpose?
You could include an implicit conversion operator from your class to bool, but personally I wouldn't. I would almost always prefer to expose a property, so you'd write:
if (myValue.MyProperty)
... I think that keeps things clear. But if you could give us more of the real context, we may be able to give more concrete advice.
Simple example:
public class MyClass {
private bool isTrue = true;
public static bool operator ==(MyClass a, bool b)
{
if (a == null)
{
return false;
}
return a.isTrue == b;
}
public static bool operator !=(MyClass a, bool b)
{
return !(a == b);
}
}
somewhere in code you can compare your object with boolean value:
MyClass a = new MyClass();
if ( a == true ) { // it compares with a.isTrue property as defined in == operator overloading method
// ...
}
You can use an implicit conversion operator to have this code:
class MyClass {
public bool Value { get; set; }
public MyClass() {
Value = true;
}
public static implicit operator bool(MyClass m) {
return m != null && m.Value;
}
}
class Program {
public static void Main() {
var myClass = new MyClass();
if (myClass) { // MyClass can be treated like a Boolean
Console.WriteLine("myClass is true");
}
else {
Console.WriteLine("myClass is false");
}
}
}
It can be used as above:
if (myClass) ...
Or like this:
if (myClass == true) ...
while your example wouldnt work, you can do something similar for your own classes to test if one equals the values of another.
http://msdn.microsoft.com/en-us/library/ms173147(v=vs.80).aspx
public static bool operator ==(ThreeDPoint a, ThreeDPoint b)
{
// If both are null, or both are same instance, return true.
if (System.Object.ReferenceEquals(a, b))
{
return true;
}
// If one is null, but not both, return false.
if (((object)a == null) || ((object)b == null))
{
return false;
}
// Return true if the fields match:
return a.x == b.x && a.y == b.y && a.z == b.z;
}
public static bool operator !=(ThreeDPoint a, ThreeDPoint b)
{
return !(a == b);
}
You can ("or make my class comparable..."), by overriding the == operator. I presume Jon Skeet overlooked that part of the question.
If you want to be able to use your value in 'if' statements, define operator true and operator false (along with the & and | operators if you want to use && and ||.) (VB equivalents)
To answer more, I would have to know what you're trying to do (in other words, why not just use bool directly?)

Why is 1 && 2 in C# false?

I got frustated with my other question. So i wrote up this example.
In C the below is true. See demo
int main()
{
printf("%d", 1 && 2);
return 0;
}
Output:
1
In C#. It is FALSE. WHY is this false?
Also i dont understand why i needed to create the bool operator in this example but not the one in my other question but no matter. Why is the below false? it makes no sense to me.
BTW the logic making the below false is described here
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
MyInt a=1, b=2;
bool res=a && b;
Console.WriteLine("result is {0}", res);
}
class MyInt
{
public int val;
public static bool operator true(MyInt t) { return t.val != 0; }
public static bool operator false(MyInt t) { return t.val == 0; }
public static MyInt operator &(MyInt l, MyInt r) { return l.val & r.val; }
public static MyInt operator |(MyInt l, MyInt r) { return l.val | r.val; }
public static implicit operator MyInt(int v) { return new MyInt() { val = v }; }
public static implicit operator bool(MyInt t) { return t.val != 0; }
}
}
}
In C there is no bool. Convention is that 0 is false and != 0 is true. if statement treated conditional expression result exactly that way.
In C++ bool was introduced. But it was compatible with old rules, 0 treated as false and false as 0, and there was implicit conversion between int and bool.
In C# it is not the same way: there is bool and int and they are not convertible to eachother. That is what C# Standard says. Period.
So when you tried to reimplement bool and int compatibility you made a mistake. You use && which is logical operator, but in C# you can't override it and only &, which is implemented as bitwise. 1 & 2 == 0 == false! here it is!
You even should not overload bitwise ones, to maintain compatibility you just have to leave operator true and false.
This code works as you expect:
class Programx
{
static void Main(string[] args)
{
MyInt a = 1, b = 2;
bool res = a && b;
Console.WriteLine("result is {0}", res);
}
class MyInt
{
public int val;
public static bool operator true(MyInt t)
{
return t.val != 0;
}
public static bool operator false(MyInt t)
{
return t.val == 0;
}
public static implicit operator MyInt(int v)
{
return new MyInt() { val = v };
}
public static implicit operator bool(MyInt t)
{
return t.val != 0;
}
}
}
result is True
Your implementations of operator& and operator| are wrong. These binary operators have bitwise meanings when applied to integral types, and when applied to either Boolean types or classes that have their own & and | operators, they have logical AND and OR semantics (being the non-short-circuiting cousins of && and ||). Correct implementations would look as follows:
operator &(MyInt l, MyInt r) {return l.val != 0 && r.val != 0);}
operator |(MyInt l, MyInt r) {return l.val != 0 || r.val != 0);}
I'll try and make this simple, since I think people are overcomplicating this.
var x = 1 & 2;
// behind the scenes: 0001 AND 0010 = 0000
Console.Write(x); // 0, as shown above
Integers can NOT be used as booleans in C#. The result of:
if (1 && 2) // compile error
var x = 1 && 2; // compile error
There is no point to asking why an Integer can not be used as a boolean in C#, it just can't. The type system does not allow it. If one were to implement their own Integer class, they could provide implicit conversions from their type to bool, but int does not do this. You also have to make a choice when overloading; do you want bitwise behaviour, or logical behaviour. You can not have both.
Some languages allow 0, "", [] as 'falsey' values. C# does not. Get over it, and use a bool if you're doing boolean logic. If all else fails, Convert.ToBoolean on an int will return true for all non-zero values.
public static MyInt operator &(MyInt l, MyInt r) { return l.val & r.val; }
If I read the linked article correctly, res = a && b will be "expanded" to:
MyInt.false(a) ? a : MyInt.&(a, b)
MyInt.false(a) is false, so evaluates to:
MyInt.&(a, b)
which "expands" to:
a.val & b.val
which is (1 & 2) == 0, and thus false.

Boolean Marshalling with LayoutKind.Explicit, Is this broken or failing as designed?

First of all the Boolean type is said to have a default marshal type of a four-byte value. So the following code works:
struct A
{
public bool bValue1;
public int iValue2;
}
struct B
{
public int iValue1;
public bool bValue2;
}
public static void Main()
{
int[] rawvalues = new int[] { 2, 4 };
A a = (A)Marshal.PtrToStructure(GCHandle.Alloc(rawvalues, GCHandleType.Pinned).AddrOfPinnedObject(), typeof(A));
Assert.IsTrue(a.bValue1 == true);
Assert.IsTrue(a.iValue2 == 4);
B b = (B)Marshal.PtrToStructure(GCHandle.Alloc(rawvalues, GCHandleType.Pinned).AddrOfPinnedObject(), typeof(B));
Assert.IsTrue(b.iValue1 == 2);
Assert.IsTrue(b.bValue2 == true);
}
Clearly these structures marshal independently just fine. The values are translated as expected. However, when we combine these structures into a "union" by declaring LayoutKind.Explicit like this:
[StructLayout(LayoutKind.Explicit)]
struct Broken
{
[FieldOffset(0)]
public A a;
[FieldOffset(0)]
public B b;
}
We suddenly find ourselves unable to correctly marshal these types. Here is the test code for the above structure and how it fails:
int[] rawvalues = new int[] { 2, 4 };
Broken broken = (Broken)Marshal.PtrToStructure(GCHandle.Alloc(rawvalues, GCHandleType.Pinned).AddrOfPinnedObject(), typeof(Broken));
Assert.IsTrue(broken.a.bValue1 != false);// pass, not false
Assert.IsTrue(broken.a.bValue1 == true);// pass, must be true?
Assert.IsTrue(true.Equals(broken.a.bValue1));// FAILS, WOW, WTF?
Assert.IsTrue(broken.a.iValue2 == 4);// FAILS, a.iValue1 == 1, What happened to 4?
Assert.IsTrue(broken.b.iValue1 == 2);// pass
Assert.IsTrue(broken.b.bValue2 == true);// pass
It's very humorous to see this express as true: (a.bValue1 != false && a.bValue1 == true && !true.Equals(a.bValue1))
Of course the bigger problem here is that a.iValue2 != 4, rather the 4 has been changed to 1 (presumably by the overlapped bool).
So the question: Is this a bug, or just failed as designed?
Background: this came from What is the difference between structures containing bool vs uint when using PInvoke?
Update: This is even stranger when you use large integer values (> 255) as only the byte that is used for the boolean is being modified to a 1, thus changing 0x0f00 to 0x0f01 for the b.bValue2. For a.bValue1 above it's not translated at all and 0x0f00 provides a false value for a.bValue1.
Update #2:
The most obvious and reasonable solution to the above issue(s) is to use a uint for the marshalling and expose boolean properties instead. Really solving the issue with a 'workaround' is not at question. I'm mostly wondering is this a bug or is this the behavior you would expect?
struct A
{
private uint _bValue1;
public bool bValue1 { get { return _bValue1 != 0; } }
public int iValue2;
}
struct B
{
public int iValue1;
private uint _bValue2;
public bool bValue2 { get { return _bValue2 != 0; } }
}
It is working as designed.
Here is what is happening:
Take the new int[] { 2, 4 } and lets marshal it into A, B, Broken, and Broken2.
The last is the same as Broken, but with fields' order reversed (first b, then a).
If we marshal the ints into these structures we get the following values in memory:
A: 1, 4
B: 2, 1
Broken: 2, 1
Broken2: 1, 4
So what is happening is the following:
When the marshaller encounters a boolean, the value of it is: bool = (original != 0);
When there are two fields that map into the same memory, the rules of the last field win
So for A, the first int gets converted to 1, for B, the second int gets converted to 1,
for Broken, since B is the last field, its rules apply, and hence the second int gets converted to 1. Similarly for Broken2.
The line commented with 'FAILS, WOW, WTF?' fails because of the way boolean comparison is performed. It is comparing 2 to 1:
IL_007e: ldc.i4.1
IL_007f: ldloca.s 3
IL_0081: ldflda valuetype Test/A Test/Broken::a
IL_0086: ldfld bool Test/A::bValue1
IL_008b: ceq
ceq ends up comparing 1 to the byte in bValue, which is 2.
The funny thing is that if (broken.a.bValue1) will test 'true' because it's non-zero.
As far as the other problem (broken.a.iValue2 == 4), it went away when I applied:
[MarshalAs (UnmanagedType.Bool)]
to both boolean fields in the structures. This makes sure the booleans are marshaled as an integer (4 bytes in .NET).
It would appear earlNameless is correct, as adding another structure of ints:
struct C
{
public int iValue1;
public int iValue2;
}
to the end of the union seems to correct at least part of the problem. However, this is still flawed since the boolean will only consider a single-byte value and as demonstrated is not dependable. Finally the best answer I've come up with is to use a custom type for the marshaling.
[Serializable]
[ComVisible(true)]
public struct BOOL : IComparable, IConvertible, IComparable<BOOL>, IEquatable<BOOL>, IComparable<bool>, IEquatable<bool>
{
private uint _data;
public BOOL(bool value) { _data = value ? 1u : 0u; }
public BOOL(int value) { _data = unchecked((uint)value); }
public BOOL(uint value) { _data = value; }
private bool Value { get { return _data != 0; } }
private IConvertible Convertible { get { return _data != 0; } }
#region IComparable Members
public int CompareTo(object obj) { return Value.CompareTo(obj); }
#endregion
#region IConvertible Members
public TypeCode GetTypeCode() { return Value.GetTypeCode(); }
public string ToString(IFormatProvider provider) { return Value.ToString(provider); }
bool IConvertible.ToBoolean(IFormatProvider provider) { return Convertible.ToBoolean(provider); }
byte IConvertible.ToByte(IFormatProvider provider) { return Convertible.ToByte(provider); }
char IConvertible.ToChar(IFormatProvider provider) { return Convertible.ToChar(provider); }
DateTime IConvertible.ToDateTime(IFormatProvider provider) { return Convertible.ToDateTime(provider); }
decimal IConvertible.ToDecimal(IFormatProvider provider) { return Convertible.ToDecimal(provider); }
double IConvertible.ToDouble(IFormatProvider provider) { return Convertible.ToDouble(provider); }
short IConvertible.ToInt16(IFormatProvider provider) { return Convertible.ToInt16(provider); }
int IConvertible.ToInt32(IFormatProvider provider) { return Convertible.ToInt32(provider); }
long IConvertible.ToInt64(IFormatProvider provider) { return Convertible.ToInt64(provider); }
sbyte IConvertible.ToSByte(IFormatProvider provider) { return Convertible.ToSByte(provider); }
float IConvertible.ToSingle(IFormatProvider provider) { return Convertible.ToSingle(provider); }
ushort IConvertible.ToUInt16(IFormatProvider provider) { return Convertible.ToUInt16(provider); }
uint IConvertible.ToUInt32(IFormatProvider provider) { return Convertible.ToUInt32(provider); }
ulong IConvertible.ToUInt64(IFormatProvider provider) { return Convertible.ToUInt64(provider); }
object IConvertible.ToType(Type conversionType, IFormatProvider provider) { return Convertible.ToType(conversionType, provider); }
#endregion
#region IComparable<bool> Members
public int CompareTo(BOOL other) { return Value.CompareTo(other.Value); }
public int CompareTo(bool other) { return Value.CompareTo(other); }
#endregion
#region IEquatable<bool> Members
public bool Equals(BOOL other) { return Value.Equals(other.Value); }
public bool Equals(bool other) { return Value.Equals(other); }
#endregion
#region Object Override
public override string ToString() { return Value.ToString(); }
public override int GetHashCode() { return Value.GetHashCode(); }
public override bool Equals(object obj) { return Value.Equals(obj); }
#endregion
#region implicit/explicit cast operators
public static implicit operator bool(BOOL value) { return value.Value; }
public static implicit operator BOOL(bool value) { return new BOOL(value); }
public static explicit operator int(BOOL value) { return unchecked((int)value._data); }
public static explicit operator BOOL(int value) { return new BOOL(value); }
public static explicit operator uint(BOOL value) { return value._data; }
public static explicit operator BOOL(uint value) { return new BOOL(value); }
#endregion
#region +, -, !, ~, ++, --, true, false unary operators overloaded.
public static BOOL operator !(BOOL b) { return new BOOL(!b.Value); }
public static bool operator true(BOOL b) { return b.Value; }
public static bool operator false(BOOL b) { return !b.Value; }
#endregion
#region +, -, *, /, %, &, |, ^, <<, >> binary operators overloaded.
public static BOOL operator &(BOOL b1, BOOL b2) { return new BOOL(b1.Value & b2.Value); }
public static BOOL operator |(BOOL b1, BOOL b2) { return new BOOL(b1.Value | b2.Value); }
#endregion
#region ==, !=, <, >, <=, >= comparison operators overloaded
public static bool operator ==(BOOL b1, BOOL b2) { return (b1.Value == b2.Value); }
public static bool operator !=(BOOL b1, BOOL b2) { return (b1.Value != b2.Value); }
#endregion
}

Categories