Best way to handle null when writing equals operator [duplicate] - c#

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How do I check for nulls in an '==' operator overload without infinite recursion?
When I overload the == operator for objects I typically write something like this:
public static bool operator ==(MyObject uq1, MyObject uq2) {
if (((object)uq1 == null) || ((object)uq2 == null)) return false;
return uq1.Field1 == uq2.Field1 && uq1.Field2 == uq2.Field2;
}
If you don't down-cast to object the function recurses into itself but I have to wonder if there isn't a better way?

As Microsoft says,
A common error in overloads of
operator == is to use (a == b), (a ==
null), or (b == null) to check for
reference equality. This instead
results in a call to the overloaded
operator ==, causing an infinite loop.
Use ReferenceEquals or cast the type
to Object, to avoid the loop.
So use ReferenceEquals(a, null) || ReferenceEquals(b, null) is one possibility, but casting to object is just as good (is actually equivalent, I believe).
So yes, it seems there should be a better way, but the method you use is the one recommended.
However, as has been pointed out, you really SHOULD override Equals as well when overriding ==. With LINQ providers being written in different languages and doing expression resolution at runtime, who knows when you'll be bit by not doing it even if you own all the code yourself.

ReferenceEquals(object obj1, object obj2)

#neouser99: That's the right solution, however the part that is missed is that when overriding the equality operator (the operator ==) you should also override the Equals function and simply make the operator call the function. Not all .NET languages support operator overloading, hence the reason for overriding the Equals function.

if ((object)uq1 == null)
return ((object)uq2 == null)
else if ((object)uq2 == null)
return false;
else
//return normal comparison
This compares them as equal when both are null.

Just use Resharper to create you Equals & GetHashCode methods. It creates the most comprehensive code for this purpose.
Update
I didn't post it on purpose - I prefer people to use Resharper's function instead of copy-pasting, because the code changes from class to class. As for developing C# without Resharper - I don't understand how you live, man.
Anyway, here is the code for a simple class (Generated by Resharper 3.0, the older version - I have 4.0 at work, I don't currently remember if it creates identical code)
public class Foo : IEquatable<Foo>
{
public static bool operator !=(Foo foo1, Foo foo2)
{
return !Equals(foo1, foo2);
}
public static bool operator ==(Foo foo1, Foo foo2)
{
return Equals(foo1, foo2);
}
public bool Equals(Foo foo)
{
if (foo == null) return false;
return y == foo.y && x == foo.x;
}
public override bool Equals(object obj)
{
if (ReferenceEquals(this, obj)) return true;
return Equals(obj as Foo);
}
public override int GetHashCode()
{
return y + 29*x;
}
private int y;
private int x;
}

But why don't you create an object member function? It can certainly not be called on a Null reference, so you're sure the first argument is not Null.
Indeed, you lose the symmetricity of a binary operator, but still...
(note on Purfideas' answer: Null might equal Null if needed as a sentinel value of an array)
Also think of the semantics of your == function: sometimes you really want to be able to choose whether you test for
Identity (points to same object)
Value Equality
Equivalence ( e.g. 1.000001 is equivalent to .9999999 )

Follow the DB treatment:
null == <anything> is always false

Related

How does overloading the equality operator == really work?

I have this piece of code in MyClass:
public static bool operator ==(MyClass lhs, MyClass rhs)
{
if (lhs == null || rhs == null)
return false;
// Other operations to check for equality
}
Going by the first line in the code, I'm comparing lhs and rhs to null. I'm not sure but I suppose that comparison itself will invoke the overload function again. And then we het to that line again, it invokes itself and so on. Sort of an infinite recursion.
But we all know that does not take place. This implies, in my opinion, that comparing with null does not invoke the equality overload. So what really occurs? How does comparing with null work?
EDIT
I stand corrected. It does call the == operator recursively (at least in LinqPad 4.5) rather than binding to object.==. There are three ways to fix this:
Overload Equals instead if you really want value equality semantics.
Cast lhs and rhs to object
Use Object.ReferenceEquals as the MSDN guidelines recommend
I suppose that comparison itself will invoke the overload function again
No - null is not a MyClass so the call uses the default meaning of == which is reference equality.
Also note that the guidelines for overloading == state that it should only be overloaded for immutable types, since the expected behavior for == is reference equality which is what happens by default. Equals implies "value equality" semantics.
In addition to D Stanley answer. To avoid such kind of surprizes (Object operator == is called), use Object.ReferenceEquals when implementing ==:
public static bool operator ==(MyClass lhs, MyClass rhs)
{
// lhs and rhs are the same instance (both are null included)
if (Object.ReferenceEquals(lhs, rhs))
return true;
else if (Object.ReferenceEquals(lhs, null) || Object.ReferenceEquals(rhs, null))
return false;
// From here we have different instances, none of them is null
// Other operations to check for equality
}

Result of calling IEquatable<T>.Equals(T obj) when this == null and obj == null?

What should IEquatable<T>.Equals(T obj) do when this == null and obj == null?
1) This code is generated by F# compiler when implementing IEquatable<T>. You can see that it returns true when both objects are null:
public sealed override bool Equals(T obj)
{
if (this == null)
{
return obj == null;
}
if (obj == null)
{
return false;
}
// Code when both this and obj are not null.
}
2) Similar code can be found in the question "in IEquatable implementation is reference check necessary" or in the question "Is there a complete IEquatable implementation reference?". This code returns false when both objects are null.
public sealed override bool Equals(T obj)
{
if (obj == null)
{
return false;
}
// Code when obj is not null.
}
3) The last option is to say that the behaviour of the method is not defined when this == null.
leppie is right. Just to elaborate on his answer (and confirm his suspicion that F# doesn't guarantee this != null): discriminated unions may be marked with the attribute [<CompilationRepresentation(CompilationRepresentationFlags.UseNullAsTrueValue)>] allowing cases to be represented by the value null. Option<'T> is such a type. The None case is represented by null at run-time. (None : option<int>).Equals(None) is syntactically valid. Here's a fun example:
[<CompilationRepresentation(CompilationRepresentationFlags.UseNullAsTrueValue)>]
type Maybe<'T> =
| Just of 'T
| Nothing
[<CompilationRepresentation(CompilationRepresentationFlags.Instance)>]
member this.ThisIsNull() = match this with Nothing -> true | _ -> false
Decompiling ThisIsNull with Reflector shows
public bool ThisIsNull()
{
return (this == null);
}
And the result:
Nothing.ThisIsNull() //true
The reason F# does this (I suspect) to optimize empty lists as null.
By adding this check, it allows one to call an instance method on a null instance without any problems.
See my blog post from a while back.
In C#, this is irrelevant.
To answer the question:
It should return true as both instances are null and deemed equal.
If this is null, the code can't be called, so that case needn't be considered (in C# anyway, there are cases where languages allow a null object to have a method dereferenced though obviously if it internally examines any of its non-existent fields it will error. Consider:
return x.Equals(y);
If x is null, we don't even get to call into Equals for the null check to count.
Hence we need only consider:
public bool Equals(T obj)
{
if(obj == null)
return false;
//logic defining equality here.
}
Where the possibility of both objects being null does come up, is when we are examining them from a static == operator override or from an IEqualityComparer<T> implementation:
public bool Equals(T x, T y)
{
if(x == null)
return y == null;
if(y == null)
return false;
//logic defining equality here.
}
Note that a useful shortcut here if equality can be lengthy to determine (e.g. comparing long strings), then we may take advantage of the fact that identity entails equality - that is something is always equal to itself, even Ayn Rand could figure that out ;) There are also algorithms that make comparing an item with itself quite common, making this shortcut well worth including. In this case the identity comparison already includes the check for both being null, so we leave it out again:
public bool Equals(T x, T y)
{
if(ReferenceEquals(x, y))
return true;
if(x == null || y == null)
return false;
//logic defining equality here.
}
For most methods I assume undefined behavior when called with this==null. That's because most programmers write their code under the assumption that this!=null, which is guaranteed by the C# specification if the calling code is written in C#.
That's why every sane caller of x.Equals(y) should either know for sure that that x is not null, or add a manual null check.
In most cases I wouldn't call Equals directly at all, but instead use EqualityComparer<T>.Default.
I would definitelly go with option 1:
if (this == null)
{
return obj == null;
}
if (obj == null)
{
return false;
}
null object always equals null object.
Sample code is in the MSDN: http://msdn.microsoft.com/en-us/library/ms131190.aspx?ppud=4
If this==null you will get a runtime exception calling Equals() on that object.

Whats the Difference between Object.Equals(obj, null) and obj == null

Almost every time I want to check object's equality to null I use the normal equality check operation
if (obj == null)
Recently I noticed that I'm using the Object.Equals() more often
if (Object.Equals(obj, null))
and while reading about null checking I fount this Is ReferenceEquals(null, obj) the same thing as null == obj?
if (ReferenceEquals(null, obj))
Whats the difference? and where/when to use each one? plus I found that the last two checks look like the same according to their summary
Object.Equals(x, y) will:
Return true if x and y are both null
Return false if exactly one of x or y is null
Otherwise call either x.Equals(y) or y.Equals(x) - it shouldn't matter which. This means that whatever polymorphic behaviour has been implemented by the execution-time type of the object x or y refers to will be invoked.
ReferenceEquals will not call the polymorphic Equals method. It just compares references for equality. For example:
string x = new StringBuilder("hello").ToString();
string y = new StringBuilder("hello").ToString();
Console.WriteLine(Object.Equals(x, y)); // True
Console.WriteLine(Object.ReferenceEquals(x, y)); // False
Console.WriteLine(x == y); // True due to overloading
Now if you're only checking for nullity, then you don't really want the polymorphic behaviour - just reference equality. So feel free to use ReferenceEquals.
You could also use ==, but that can be overloaded (not overridden) by classes - it is in the case of string, as shown above. The most common case for using ReferenceEquals in my experience is when you're implementing ==:
public bool operator ==(Foo x1, Foo x2)
{
if (ReferenceEquals(x1, x2))
{
return true;
}
if (ReferenceEquals(x1, null) || ReferenceEquals(x2, null))
{
return false;
}
return x1.Equals(x2);
}
Here you really don't want to call the == implementation, because it would recurse forever - you want the very definite reference equality semantics.

Why casting to object when comparing to null?

While browsing the MSDN documentations on Equals overrides, one point grabbed my attention.
On the examples of this specific page, some null checks are made, and the objects are casted to the System.Object type when doing the comparison :
public override bool Equals(System.Object obj)
{
// If parameter is null return false.
if (obj == null)
{
return false;
}
// If parameter cannot be cast to Point return false.
TwoDPoint p = obj as TwoDPoint;
if ((System.Object)p == null)
{
return false;
}
// Return true if the fields match:
return (x == p.x) && (y == p.y);
}
Is there a specific reason to use this cast, or is it just some "useless" code forgotten in this example ?
It is possible for a type to overload the == operator. The cast to object ensures that the original definition is used.
As others said, the type might override the == operator. Therefore, casting to Objectis equivalent to if (Object.ReferenceEquals(p, null)) { ... }.
I believe casting to System.Object would get you around any operator overloading that TwoDPoint might have.
It likely exists to avoid confusion with an overloaded == operator. Imagine if the cast did not exist and the == operator was overloaded. Now the p == null line would potentially bind to the operator ==. Many implementations of operator == simply defer to the overridden Equals method. This could easily cause a stack overflow situation
public static bool operator==(TwoDPoint left, TwoDPoint right) {
return left.Equals(right);
}
public override bool Equals(System.Object obj) {
...
TwoDPoint p = obj as TwoDPoint;
if ( p == null ) { // Stack overflow!!!
return false;
}
...
}
By casting to Object the author ensures a simple reference check for null will occur (which is what is intended).
This might have been part of a larger sample where the == operator was overloaded. In that case, using obj == null could have resulted in StackOverflow if TwoDPoint.Equals(object) was invoked as part of the == definition.

When, typically, do you use == equality on a reference typed variable in Java / C#?

As a kind of follow up to the question titled "Difference Between Equals and ==": in what kind of situations would you find yourself testing for reference equality in Java / C#?
Consolidating answers ...
When, typically, do you use ==
equality on a reference typed variable
in Java / C#?
1. To check for null:
if (a == null) ...
2. For efficiency when you are constructing an equals implementation:
boolean equals(Object o) {
if (o == null) return false;
if (this == o) return true;
// Some people would prefer "if (!(o instanceof ClassName)) ..."
if (getClass() != o.getClass()) return false;
// Otherwise, cast o, leverage super.equals() when possible, and
// compare each instance variable ...
3. For efficiency when you are comparing enums or comparing objects of a class designed such that comparing object identity is equivalent to checking object equivalence (e.g. Class objects):
enum Suit { DIAMONDS, HEARTS, CLUBS, SPADES }
class SomeCardGame {
...
boolean static isATrumpCard(Card c) {
return (c.getSuit() == TRUMP_SUIT);
}
}
4. When you really intend to check object identity, not object equivalence, e.g. a test case that wants to make sure a class isn't giving up a reference to an internal data structure instance.
boolean iChoseNotToUseJUnitForSomeReasonTestCase() {
final List<String> externalList = testObject.getCopyOfList();
final List<String> instanceVariableValue =
getInstanceVariableValueViaCleverReflectionTrickTo(testObject, "list");
if (instanceVariableValue == externalList) {
System.out.println("fail");
} else {
System.out.println("pass");
}
}
Interestingly, for point #3, one article suggests using equals is safer than using .equals() because the compiler will complain if you attempt to compare to object references that are not of the same class (http://schneide.wordpress.com/2008/09/22/or-equals/).
For Java, most commonly to see if a reference is null:
if (someReference == null) {
//do something
}
It is also pretty common with enums, but the most common place to use it that I've seen is in a properly implemented equals method. The first check will check for reference equality and only do the more expensive calculation if that returns false.
Because it's so fast and simple, == is routinely part of the Equals() function. If two objects are ==, then they're Equals, and you don't need any further processing. For primitives in Java, == is your only option (I don't think that's true of C#, but am not sure). I'll use == to test for null (although more frequently it's !=). Other than that... Stick with Equals(). It's rare and probably a sign of trouble to need == over Equals.
You can use it for quick equality checks.
For example if you are doing a compare with some very large objects that may take a while to iterate through, you can save time to see if they are referring to the same object first
Compare(LargeObj a, LargeObj b) {
if (a == b)
return true;
// do other comparisons here
}
In C#, the == operator may be overloaded, which would mean that you can compare reference types for LOGICAL equality.
Any time the implementer of a class thought that it would be logical to compare equality, you may do so using their methods.
This being said, be careful when checking if (a == b) in C#. This MAY be a reference equals, or it MAY be a logical comparison.
In order to keep the two cases distinct, it could be a good idea to use the two following methods, just to be clear:
object.ReferenceEquals(a, b)
a.Equals(b)
The first one is a reference comparison, and the second is usually a logical one.
here is a typical == overload, just for reference:
public static bool operator ==(RRWinRecord lhs, RRWinRecord rhs)
{
if (object.ReferenceEquals(lhs, rhs))
{
return true;
}
else if ((object)lhs == null || (object)rhs == null)
{
return false;
}
else
{
return lhs.Wins == rhs.Wins &&
lhs.Losses == rhs.Losses &&
lhs.Draws == rhs.Draws &&
lhs.OverallScore == rhs.OverallScore;
}
}
Try to avoid == with objects that are normally defined with final static and then passed as members in classes that are serialized.
For example (before we had enums) I had a class defined that simulated the idea of an enumeration. Since the constructor was private and all allowed instances were defined as final statics I wrongly assumed that == was always safe to use on these objects.
For example (typing code without compiling, so excuse me if there are some issues with the code)
public class CarType implements Serializable {
public final static CarType DODGE = new CarType("Dodge");
public final static CarType JEEP = new CarType("JEEP");
private final String mBrand;
private CarType( String pBrand ) {
mBrand = pBrand;
}
public boolean equals( Object pOther ) {
...
}
}
The CarType instances were serialized when used in other objects... but after materialisation (on a different JVM instance) the == operation failed.
Basically, you can use == when you "know" that "==" is equivalent to ".equals" (in Java).
By doing so, you can gain performance.
A simple example where you'll see this is in a .equals method.
public boolean equals(Object o) {
// early short circuit test
if (this == o) {
return true;
}
// rest of equals method...
}
But in some algorithms, you have good knowledge of the objects you're working with, so you can rely on == for tests. Such as in containers, working with graphs, etc.
My personal preference (C#) is to always leave == to mean reference equality (referring to the same object). If I need logical equivalence, I'll use Equals<T>. If I follow this rule uniformly, then there's never any confusion.

Categories

Resources