needs overload operator< and null check - c#

I´m overloading the lessthan-operator in c# and I`m wondering whether this needs to check for null. Below you can find an Example:
public static bool operator <(MyClass x, MyClass y)
{
if (x == null && y == null)
{
return false;
}
if (x == null)
{
return true; //false?
}
if (y == null)
{
return false; //true?
}
return x.Value < y.Value;
}
Or is this correct:
public static bool operator <(MyClass x, MyClass y)
{
return x.Value < y.Value;
}
I didn´t find any instruction on this. But maybe I missed something.

The answer depends on your intended usage pattern. If you plan to have nulls in the mix, and you would like to consider null values to be less than non-null values, then your implementation is correct; if you would like to consider null values to be greater than non-null objects, then the commented out return values (false and true) should be used instead. If you do not plan to allow nulls in the mix, throwing an ArgumentNullException or allowing NullReferenceException would be the right choice.

Both approaches are correct (for different values of correct).
If x or y are likely to be null and that has a valid meaning in your case then go with the first approach.
If x and y are highly unlikely to be null then go with the second and let any exceptions propagate to the calling code for handling.

Personally I would throw a ArgumentNullException if either x or y are null, which should be an exceptional circumstance.

A custom operator is little more than a static method. Moreover, operators in generals shouldn't normally throw exceptions. Which means you need those null-checks if MyClass is a reference-type.
By the way, it's conventional for nulls to be less than non-nulls, which makes your proposed implementation idiomatic.

It's a bad idea to overload operators on classes. It's ok for structs though.
If you do decide to overload an operator on a class, you will either have to:
a. Include null-check into your logic
b. Throw exceptions when null is passed in
c. Don't null check and allow for NullReferenceExceptions (bad)
Basically, it's a bad idea to overload an operator on a class. I'd either turn your class into a struct, or just implement an interface such as IComparable<T> / IEquatable<T> which has guidelines when null values are used in comparisons.

Related

Does the order of operands matter for an overloaded == operator in C#

I am using a 3rd party tool (Unity3d), where one of the fundamental base classes overloads the == operator (UnityEngine.Object).
The overloaded operator's signature is:
public static bool operator == (UnityEngine.Object x, UnityEngine.Object y)
Does the order in which the comparison is made have any effect on whether this overloaded operator is used ?
To illustrate, should both of these use the overloaded operator and return the same result ?
// initialize with some value
UnityEngine.Object a = ....
Debug.Log(a == null);
Debug.Log(null == a);
The reason i'm asking is because i'd like to (sometimes) avoid this overloaded behaviour (use the default == operator), and was wondering whether flipping the order would assist in that ?
(There could be another option - casting the operands to System.object, but I am not 100% sure that works).
Well, it's possible that the two calls wouldn't be the same, if the operator had been overloaded badly. Either there could be one overload, and it could be written in a way which compares the operands asymmetrically, or the two statements could call different overloads.
But assuming it's been overloaded properly, that should be absolutely fine. That's if you want to call the overloaded operator, of course. In situations where you don't, I'd make that clear using ReferenceEquals.
I would personally recommend the if (a == null) approach, as I find it easier to read (and I believe many others do too). The "yoda" style of if (null == a) is sometimes used by C programmers who fear typos, where if (a = null) would be an assignment and a valid statement... albeit with a warning in decent C compilers.
Here's an example of a badly implemented set of overloads, where the operand order matters, because null is convertible to both string and Test:
using System;
class Test
{
public static bool operator ==(Test t, string x)
{
Console.WriteLine("Test == string");
return false;
}
public static bool operator !=(Test t, string x)
{
Console.WriteLine("Test != string");
return false;
}
public static bool operator ==(string x, Test t)
{
Console.WriteLine("string == Test");
return false;
}
public static bool operator !=(string x, Test t)
{
Console.WriteLine("string != Test");
return false;
}
static void Main(string[] args)
{
Test t = null;
Console.WriteLine(t == null);
Console.WriteLine(null == t);
}
}
Now that the question has been updated, we can tell that's not the case... but the implementation could still be poor. For example, it could be written as:
public static bool operator == (UnityEngine.Object x, UnityEngine.Object y)
{
// Awful implementation - do not use!
return x.Equals(y);
}
In that case, it will fail with a NullReferenceException when x is null, but succeed if x is non-null but y is null (assuming Equals has been written properly).
Again though, I'd expect that the operator has been written properly, and that this isn't a problem.
UPDATE after updating the question:
If you want to avoid calling the overloaded function when comparing to null, use ReferenceEquals:
if(a.ReferenceEquals(null)) ...
OLDER ANSWER, RENDERED OBSOLETE AND ALSO WRONG BY #Jon Skeet...
According to this, overload resolution of binary operator with X and Y as arguments is done by first taking the union of all operators defined by X and by Y.
So a==b results in exactly the same overload resolution as b==a.
The link is from 2003, but I doubt Microsoft has changed something since, it would have broken a lot of older code.
Update: Although I witnessed this behaviour in prior versions of Unity, I couldn't reproduce it in a test I performed right after writing this answer. May be Unity changed the == operator behaviour, or behaviour of implicit conversion of UnityEngine.Object to bool; however, I would still advocate using the overridden == operator instead of trying to avoid it.
The way Unity in particular overrides == operator is very frustrating, but also fundamental for how you have to work with the engine. After the UnityObject gets destroyed, by calling Destroy (some time after the call) or DestroyImmediate (immediately after the call, as the name would suggest), the comparison of this object to null returns true, even though it's not a null reference.
It's completely unintuitive for C# programmers, and can create a lot of truly WTF moments before you figure this out. Take this, for example:
DestroyImmediately(someObject);
if (someObject)
{
Debug.Log("This gets printed");
}
if (someObject != null)
{
Debug.Log("This doesn't");
}
The reason I'm explaining that is because I perfectly understand your desire to avoid this strange overridden behaviour, especially if you had C# experience before working with Unity. However, as with a lot of other Unity-specific stuff, it might actually be better to just stick to the Unity convention instead of trying to implement everything in the C#-correct way.

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.

Conditional Statements difference

Is there any difference between below two statements
if (null != obj)
and
if (obj != null)
If both treated same which will be preferable?
The first is a Yoda condition. Use it you should not.
The difference here is the code generated. The two will not generate the exact same code, but in practice this will have no bearing on the results or performance of the two statements.
However, if you create your own types, and override the inequality operator, and do a poor job, then it will matter.
Consider this:
public class TestClass
{
...
public static bool operator !=(TestClass left, TestClass right)
{
return !left.Equals(right);
}
}
In this case, if the first argument to the operator is null, ie. if (null != obj), then it will crash with a NullReferenceException.
So to summarize:
The code generated is different
The performance and end results should be the same
Except when you have broken code in the type involved
Now, the reason I think you're asking is that you've seen code from C, which typically had code like this:
if (null == obj)
Note that I switched to equality check here. The reason is that a frequent bug in programs written with old C compilers (these days they tend to catch this problem) would be to switch it around and forget one of the equal characters, ie. this:
if (obj = null)
This assigns null to the variable instead of comparing it. The best way to combat this bug, back then, would be to switch it around, since you can't assign anything to null, it's not a variable. ie. this would fail to compile:
if (null = obj)
No, but the second way is more common and more readable (and more logical in my opinion)
No, there is not. It's exactly the same.
The style null == obj is sometimes just used to prevent the common typo obj = null to not accidently assign null to a variable, but with != there's absolutely no reason to do so.
In .NET it won't actually compile for the typo obj = null.
So the compiler prevents you from accidently doing it.
The Yoda condition comes originally from other languages, where this compiler feature is missing.
They are exactly the same.
Some people prefer to put the null as the first part of the expression to avoid errors like this
if (obj = null) // should be obj == null
But of course this doesn't apply to the != operator, so in your example it's just a difference of style.
First type of statement came from C/C++, where was possible to pass not boolean values to condition verification. E.g. anything not 0 was true, and zero was false:
if (5) { } // true
if (0) { } // false
Sometimes it created problems if you forgot to type one '=' char:
if (x = 5) { } // this was true always and changed x value
if (x == 5) { } // this was true, if x was equal to 5
So, Yoda syntax was used, to receive compiler error in case one '=' was missed:
if (5 = x) { } // this was generating compiler error for absent-minded programmers
if (5 == x) { } // this was true, if x was equal to 5
C# allow only boolean value in conditions, So
if (x = 5) { } // this won't compile
if (x == 5) { } // this is true, if x was equal to 5
What about boolean types?
if (y = true) { }
if (y == true) { }
Well, this is useless code, because you can just write if (y).
Conclusion: Yoda syntax is gone with C/C++ and you do not need to use it anymore.
The use of the first form
if (blah == obj)
stems from the days when compilers would not catch if (obj = blah) i.e. unintentional assignment, unless compile warning level was set to maximum

After overloading the operator==, how to compare if two variables points at the same object?

Overloading the comparison operator, how to compare if the two variables points to the same object(i.e. not value)
public static bool operator ==(Landscape a, Landscape b)
{
return a.Width == b.Width && a.Height == b.Height;
}
public static bool operator !=(Landscape a, Landscape b)
{
return !(a.Width == b.Width && a.Height == b.Height);
}
Use the Object.ReferenceEquals static method.
Of course, in order for the == and != method to retain their full functionality, you should also be overriding Equals and GetHashCode so that they return a consistent set of responses to callers.
Try a.ReferenceEquals(b);
To check whether both points to same object. You should use Object.ReferenceEquals method. It will return true if both are same or if both are null. Else it will return false
I know its an old question, but if you're going to overload the == or Object.Equals method, you should also overload the reverse operator !=.
And in this case, since you're comparing internal numbers, you should overload the other comparison operators <, >, <=, >=.
People who consume your class in the future, whether it be third-party consumers, or developers who take over your code, might use something like CodeRush or Refactor, that'll automatically "flip" the logic (also called reversing the conditional) and then flatten it, to break out of the 25 nested if's syndrome. If their code does that, and you've overloaded the == operator without overloading the != operator, it could change the intended meaning of your code.

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

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

Categories

Resources