-2

Possible Duplicates:
What is “Best Practice” For Comparing Two Instances of a Reference Type?
How do I check for nulls in an '==' operator overload without infinite recursion?

I have a class called "Criterion" and i want to implement == operator,but I'm struggling with the following problem :

When i implement the == operator, I'm checking if one or both of my instances are null, but when i do it, it causes a recursive call for == and then i get "StackOverflow" (he he) exception.

Technically i can implement the Equals operator and not override the ==, but the code will be much more readable if i implement the == operator.

Here is my code :

public static bool operator == (Criterion c1, Criterion c2)
{
    if (null == c1)
    {
        if (null == c2)
            return true;
        return false;
    }
    if (null == c2)
        return false;                
    if ((c1.mId == c2.mId) && (c1.mName == c2.mName))
        return true;
    return false;
}
Community
  • 1
  • 1
osh
  • 81
  • 1
  • 5

2 Answers2

11

Try ReferenceEquals:

public static bool operator ==(Criterion c1, Criterion c2) {
    var nullC1 = ReferenceEquals(null, c1);
    var nullC2 = ReferenceEquals(null, c2);
    if (nullC1 && nullC2)
        return true;

    if (!nullC1 && !nullC2)
        if (c1.mId == c2.mId && c1.mName == c2.mName)
            return true;

    return false;
}
Rudi Visser
  • 21,350
  • 5
  • 71
  • 97
CC Inc
  • 5,842
  • 3
  • 33
  • 64
  • +1 for reference type validation. – sajanyamaha Jan 20 '13 at 19:22
  • you dont need `Object` in the beginning. – DarthVader Jan 20 '13 at 19:24
  • @DarthVader Thanks for the readability suggestion! – CC Inc Jan 20 '13 at 19:26
  • I would also use `ReferenceEquals`. But it is possible to specify which overload of `==` to call, just as for usual methods, so one can also say `if ((object)null == (object)c1) { ... }`. Actually it's probably enough to cast just one side of the `==` to `object`, not both, but I would cast both operands for clarity (or use `ReferenceEquals`). – Jeppe Stig Nielsen Jan 20 '13 at 19:26
  • this is wrong. this function is not doing anything useful. Instead it should impleemnt IEquatable. i hope noone uses this. – DarthVader Jan 20 '13 at 19:32
  • @DarthVader This is what the OP requested. – CC Inc Jan 20 '13 at 19:32
  • @DarthVader Of course it helps him, since his specific question was about overriding `==` operator. Saying that a working function is doing nothing useful is more "wrong" and "terrible" than a correct answer to a question. – Rudi Visser Jan 20 '13 at 19:35
  • if you do `ReferenceEquals(foo, bar)`. that is enough. `ReferenceEquals(foo1.mId, foo2.mId) ....` if the object references are same, checking fields is overkill as well. so your answer is just introducing reference equals blindly. – DarthVader Jan 20 '13 at 19:37
  • **Don't** use `ReferenceEquals` for the fields/properties `mId` and `mName`! That's wrong. Suppose `mId` were a value type, like `int` or `Guid`. You wold get boxing and compare two different boxes which always returns `false`. And suppose `mName` where a `string`. You would not check for `string` equality, but for equality of references, which is also an error. – Jeppe Stig Nielsen Jan 20 '13 at 19:40
  • You shouldn't remove it completely. You should probably use `foo1.mId == foo2.mId` and `foo1.mName == foo2.mName` (but it depends of the (compile-time) types of `mId` and `mName`). – Jeppe Stig Nielsen Jan 20 '13 at 19:54
  • Hm, this code is pretty horrible. The very first version of your answer had a much terser version that was vastly superior. – Konrad Rudolph Jan 20 '13 at 19:55
  • @JeppeStigNielsen Feel free to change it yourself if I left off anything :) – CC Inc Jan 20 '13 at 19:55
  • @KonradRudolph I changed it back, as my new code seems to have some controversy. – CC Inc Jan 20 '13 at 19:56
  • As far as I can tell, this code is pretty much what OP's original overload was meant to achieve. – Rudi Visser Jan 20 '13 at 20:04
1

I'd do it like this:

bool isC1Null = Object.Equals(c1, null)
bool isC2Null = Object.Equals(c2, null)
if (isC1Null ^ isC2Null)
{
    return false
}
if (isC1Null && isC2Null)
{
    return true
}
//your code
It'sNotALie.
  • 22,289
  • 12
  • 68
  • 103