Howto overload equality operator of struct and null
- I have created a new generic value type which is called NullableWithFlavor. It's like System.Nullable<T>, but with an extra NullFlavor property.
It can be declared and used as follows:
NullableWithFlavor<int> nwf = 3; //Not nulled NullableWithFlavor<int> nwf = NullFlavor.TemporarilyUnavailable; //Nulled with a flavor
Because it is a nullable type I would like it to return 'True' when compared with null. Just like System.Nullable<T>.
bool b = nwf.HasValue; //Returns false bool b = (nwf == null); //Returns false <-- I want this to return True
This doesn't work by default. I tried overloading the '==' operator, but the only possible solution I found was a comparison with any object (System.Object). The negative effect is that the compiler doesn't generate an error anymore when comparing my NullableWithFlavor<T> with a string for example.
I tried figuring out how System.Nullable<T> works by using Reflector. Unfortunately I didn't found any clues. A compiler trick maybe?
So, fellow developers, can you tell me how to solve the problem of overloading the equality operator for structs?
Thanks in advance,
Edwin
Answers
- The only way you can use null with your struct is by using Nullable<T>. For assignment you need to implement the implicit or explicit operator overloads. Below is an example.
byte x = 20;
int y = x; // Implicit
x = (byte) // explicit.
Operator Overloading Tutorial
http://msdn.microsoft.com/en-us/library/aa288467(VS.71).aspx// Implicit conversion from bool to DBBool. Maps true to
// DBBool.dbTrue and false to DBBool.dbFalse:
public static implicit operator DBBool(bool x)
{
return x? dbTrue: dbFalse;
}
// Explicit conversion from DBBool to bool. Throws an
// exception if the given DBBool is dbNull, otherwise returns
// true or false:
public static explicit operator bool(DBBool x)
{
if (x.value == 0) throw new InvalidOperationException();
return x.value > 0;
}- Edited byAbdElRaheim Friday, August 01, 2008 7:08 AMmsdn documentation link
- Marked As Answer byFigo FeiMSFT, ModeratorMonday, August 04, 2008 8:23 AM
Nullable<T> is a very curious beast... first off, it doesn't actually overload the == operator; this "== null" behavior is done by the compiler, which substitutes with .HasValue if it recognises a Nullable<T> operand. To cover the cases when we don't know the operand is Nullable<T> (unrestricted generics, for example), the runtime also has changes such that an empty Nullable<T> boxes to null, and a null unboxes to an empty Nullable<T>; you will not be able to repeat this special case, as such structs will always end up boxed, so will *not* be null. Finally, the language has sanity clauses such that Nullable<T> does not satisfy *either* of the generic constraints ": class" / ": struct".
I think your best bet is just to add a .HasValue property and use that.
Marc- Edited byMarc GravellMVPFriday, August 01, 2008 7:36 AMtypo
- Marked As Answer byFigo FeiMSFT, ModeratorMonday, August 04, 2008 8:24 AM
All Replies
- The only way you can use null with your struct is by using Nullable<T>. For assignment you need to implement the implicit or explicit operator overloads. Below is an example.
byte x = 20;
int y = x; // Implicit
x = (byte) // explicit.
Operator Overloading Tutorial
http://msdn.microsoft.com/en-us/library/aa288467(VS.71).aspx// Implicit conversion from bool to DBBool. Maps true to
// DBBool.dbTrue and false to DBBool.dbFalse:
public static implicit operator DBBool(bool x)
{
return x? dbTrue: dbFalse;
}
// Explicit conversion from DBBool to bool. Throws an
// exception if the given DBBool is dbNull, otherwise returns
// true or false:
public static explicit operator bool(DBBool x)
{
if (x.value == 0) throw new InvalidOperationException();
return x.value > 0;
}- Edited byAbdElRaheim Friday, August 01, 2008 7:08 AMmsdn documentation link
- Marked As Answer byFigo FeiMSFT, ModeratorMonday, August 04, 2008 8:23 AM
Nullable<T> is a very curious beast... first off, it doesn't actually overload the == operator; this "== null" behavior is done by the compiler, which substitutes with .HasValue if it recognises a Nullable<T> operand. To cover the cases when we don't know the operand is Nullable<T> (unrestricted generics, for example), the runtime also has changes such that an empty Nullable<T> boxes to null, and a null unboxes to an empty Nullable<T>; you will not be able to repeat this special case, as such structs will always end up boxed, so will *not* be null. Finally, the language has sanity clauses such that Nullable<T> does not satisfy *either* of the generic constraints ": class" / ": struct".
I think your best bet is just to add a .HasValue property and use that.
Marc- Edited byMarc GravellMVPFriday, August 01, 2008 7:36 AMtypo
- Marked As Answer byFigo FeiMSFT, ModeratorMonday, August 04, 2008 8:24 AM
