Skip to main content
gamedev.net
🔒 Locked

C# and Operator Overloading

Started by FenixRoA Feb 14, 2007 at 5:34 PM 6 replies 1.1k views
Original Post
FenixRoA
FenixRoA
Ok, so I have an object called Date. For any two dates A and B the following conditions must be met in order for them to be equivalent A.day == B.day A.month == B.month A.year == B.year For simplicities sake I'd like to be able to simply write: A == B So I added this function to my Date class.
[source lang = "c#"]
public static operator ==(Date A, Date B)
{
    return A.day == B.day && A.month == B.month && A.year == B.year;
}

Sweet, so everything is dandy. Except Date should still be just an object (that is allocated on the heap with a pointer), so I expected the following to be a valid test:
[source lang = "c#"]
Date outp;
...
if (outp == null)
...

Instead of getting a true or false result, an exception is thrown claiming I'm trying to access a null reference. Upon further inspection, the error was thrown from the overloaded == operator in that B was assigned "null", so when it tried to evaluate B.day I got nailed. I guess that kinda makes sense (altho, not really to me). So I tried modifying the overloaded operator using the following code (although I was sure it wouldn't work).
[source lang = "c#"]
public static operator ==(Date A, Date B)
{
    if (A == null || B == null)
         return A == B;
    return A.day == B.day && A.month == B.month && A.year == B.year;
}

And as expected I just end up with a stack overflow (due to the infinite recursion). If anyone has any pointers for me, that'd be great. Am I overloading == wrong? Or is there a different way to check if the pointer is null within the == operator? I'm getting a warning that I should overload Object.Equals in Date. Is there some way to use this to check if the pointer is a null object? Thanks for your time and consideration, ~FenixRoA
dalep
dalep
Default == handling calls object.ReferenceEquals. Your overload doesn't mean the same thing - its duplicating the == operation for ValueTypes. You need something like this:

public static operator ==(Date A, Date B){    if (A == null || B == null)         return object.ReferenceEquals(A, B);    return A.day == B.day && A.month == B.month && A.year == B.year;}
Julian90
Julian90
Dalep, shouldnt that be...
public static operator ==(Date A, Date B){    if (object.ReferenceEquals(A, null) || object.ReferenceEquals(B, null))         return object.ReferenceEquals(A, B);    return A.day == B.day && A.month == B.month && A.year == B.year;}

Otherwise it will recurse on A == null.
dalep
dalep
Oh, I suppose it would. Good point.

This sort of thing is why I'm not in the habit of overriding == ;)
Xai
Xai
the overloading of equality in .net is somewhat tricky, especially when getting into the reference type, value type, and reference type with value semantics ideas ... and roll GetHashCode() into the mix (2 items that are == should have same hash code and some other stuff).

The book "Effective C#" covers these topics in great length and detail (almost too much) ... I recommend it.
Nypyren
Nypyren
For equality tests in reference types you should probably be using int GetHashCode() and bool Equals(object o).

Most collection classes will use GetHashCode and/or Equals when you call "Contains(YourType)" or "void Remove(YourType)". This is also how the 'Event' class knows how to properly remove a delegate when you say "MyEvent -= new EventHandler(HandlerFunc);"
benryves
benryves
What's wrong with the DateTime structure? This should be able to do what you need it to, with the advantage of being a standard type.
[Website] [+++ Divide By Cucumber Error. Please Reinstall Universe And Reboot +++]
Nitage
Nitage
Quote:
For simplicities sake I'd like to be able to simply write: A == B

That's not a good idea.

The convention is C# is that == always returns a comparrison of the two references(for reference types).

Override the Equals(Object) method.

See here for a more detailed explanation.

Quote:
Original post by benryves
What's wrong with the DateTime structure? This should be able to do what you need it to, with the advantage of being a standard type.


QTF

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.