Microsoft Developer Network > Forums Home > Visual C# Forums > Visual C# Language > Howto overload equality operator of struct and null
Ask a questionAsk a question
 

AnswerHowto overload equality operator of struct and null

  • Friday, August 01, 2008 6:39 AMCheetah Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Has Code
    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

  • Friday, August 01, 2008 7:06 AMAbdElRaheim Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code
    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;
    }

  • Friday, August 01, 2008 7:35 AMMarc GravellMVPUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer

    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

All Replies

  • Friday, August 01, 2008 7:06 AMAbdElRaheim Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code
    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;
    }

  • Friday, August 01, 2008 7:35 AMMarc GravellMVPUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer

    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