Check if object is null without using == - c#

In my program, I have objects derived from Dictionary. I need to check if 2 objects are equal, so I made an overload operator ==.
But at a later point, I need to check if a object is null.
If (object == null)
{...}
So at this point, the program goes into the overload operation I have defined, but will throw a NullReferenceException, since one of the objects to compare is null.
So within the overload operation, I need to check if one object is null, but without using ==, since that would give me a StackOverflowException.
How can I check this?

In my program, I have objects derived from Dictionary.
I would strongly reconsider deriving from Dictionary in the first place. That's very rarely a good idea. Favour composition over inheritance in general, and think very carefully about how you want equality (and hash codes) to behave in the face of mutable data. It's usually a bad sign if two objects are equal at one point and then not equal later.
So at this point, the program goes into the overload operation I have defined, but will throw a NullReferenceException, since one of the objects to compare is null.
That's the problem. Your overloaded == operator should not throw an exception - it should compare the value with null.
Typically an overload of == looks something like this:
public static bool ==(Foo left, Foo right)
{
if (ReferenceEquals(left, right))
{
return true;
}
if (ReferenceEquals(left, null))
{
return false;
}
// Equals should be overridden, and should be handling the case where
// right is null (by checking with ReferenceEquals too). Also consider
// implementing IEquatable<Foo>
return left.Equals(right);
}
Here Object.ReferenceEquals is used to perform the reference identity comparison. You could use this outside (in the code that you're currently considering changing) but it would be cleaner just to make == behave correctly.

You either need to cast to object,
(object)obj == null
or use object.ReferenceEquals(obj, null);
(object is not a nice name for an object)

You have to check for null in your implementation of overriden ==, following these guidelines for example :
http://msdn.microsoft.com/en-us/library/ms173147%28v=vs.80%29.aspx
You could also use
object.ReferenceEquals(myInstance, null);
Please note that overriding base operators such as == and/or directly overriding .Net base types such as Dictionary are both not very good practices.

overriding the == operator, as you have discovered, has non-obvious side effects and generally should be avoided.
You might consider having your object implement IComparable instead, and then calling CompareTo instead of ==.

use the is null operator from c# 7
if(object is null)...

Related

How Does FirstOrDefault Test for Equality?

I have a reference type that implements the IEquatable Interface. I have a Hashset that contains a single object. I then create an object that, by IEquatable's standards are example the same. But, when I run
var equivalentEntry = _riskControlATMEntries[grouping.Key].FirstOrDefault(e => e == atmEntry);
on the object I get null.
On the otherhand when I do
var equivalentEntry = _riskControlATMEntries[grouping.Key].FirstOrDefault(e => e.Equals(atmEntry));
I get the object that is considered equal based on the IEquatable interface's implementation.
So why does a HashSet rely on public bool Equals(ReferenceType other) but FirstOrDefault does not? What equality is the == operator in FirstOrDefault(e => e == other) looking for?
FirstOrDefault doesn't compare items for equality at all. You provided a filtering delegate that uses the == operator to compare the two objects in one case and used the Equals method in the other.
The == operator does whatever the class defines it to do by that type, or if not defined, by the closest base type that does (with object being the base type that is always there, and will always have a definition if nothing better was defined; it will compare objects based on their reference). Good design says that you should make sure the == operator for a class is defined to behave exactly the same as the Equals method, but nothing in the language forces you to do this, and apparently this class doesn't ensure they're the same, and it's unsurprisingly causing you problems.

How to use class instance in if condition that ignore "!= null" [duplicate]

This question already has answers here:
Why do if statements in Unity3d C# allow objects that are not bools?
(2 answers)
Closed 4 years ago.
I use unity, the I try following code:
class C
{
}
void m()
{
var c = GetComponent<Collider>();
if (c)
{
}
var c2 = new C();
if (c2)
{
}
}
the Rider syntax check show:
if (c) syntax is correct and if (c2) raise syntax err, I hope if (c2) syntax right, how should i modify my class C
First off: the design of the unity library here is bad C# API design and you should not attempt to replicate it. It is not idiomatic in C# to check objects for nullity with if(c). You should always check for nullity with if (c != null) and you should design your objects to be checked for null like that.
The only time that you would typically enable if(c) style checking is if the object logically represents a Boolean without actually being a bool. For example, suppose you have a type SecurityCheck that represents whether a user passed a security check or not; you might have more information in an instance than just a bool, but you might want to be able to use it in contexts where a bool is expected.
In that case there are two ways to do it.
If an instance can be converted to bool then you write a user-defined implicit conversion to bool.
If you want to preserve the content of the instance in custom implementations of & and | then you should provide custom implementations of operators |, &, true and false. If you do so then if, while, and so on, will use operator true to determine if the condition is met.
But again: do not emulate the design of Unity here. Do not make conversions to bool that just check nullity. That's not the way we check for nullity in C#. If you want to check for null you should write a null check.
Readability should always be a higher priority so doing checks like if(c != null) or if(c == null) aren't a bad thing(They are a good thing), it shows that you meant to enter that function specifically for those circumstance were if(!c) can sometimes be misinterpreted because someone misses ! but to answer your question you can change your Class C to this:
class C
{
public static implicit operator bool(C obj)
{
return obj != null;
}
}
Be aware though, that just because you can if(collider) an object does not necessarily mean that implicit conversion means it isn't null it can mean something else. In the example code I posted it does check if the object isn't null.
The check you have shown for c2 will not work in C# (as opposed to, for example, Javascript).
Instead, you have to explicitly test against null. Or you can use the null-conditional operators.
All of the following variants will prevent NullReferenceException when calling DoSomething().
Check for null and throw:
if (c2 == null) {
throw new ArgumentNullException(nameof(c2));
}
c2.DoSomething();
Check for not null and do work:
if (c2 != null) {
c2.DoSomething();
}
Use null-conditional operator:
c2?.DoSomething(); // will do nothing if c2 is null
I would check the null state of c2 by simply using:
if (c2 != null)
This is standard, clear, and concise.
We often like to make our code ever more concise, hence trying to simplify the logic down to if (c2), but it's not clear that the object returned from the C() constructor can be implicitly converted to a bool. Even if a C object could be implicitly converted to a bool, that would be uncommon, and so programmers who come along after you might wonder why/how you're checking whether the object is null that way.
To take this case even further, I would check for the null state of c in the same way instead of relying on GetComponent<Collider>() to return a bool. Often, clarity is preferred over brevity.

Comparing boxed value types

Today I stumbled upon an interesting bug I wrote. I have a set of properties which can be set through a general setter. These properties can be value types or reference types.
public void SetValue( TEnum property, object value )
{
if ( _properties[ property ] != value )
{
// Only come here when the new value is different.
}
}
When writing a unit test for this method I found out the condition is always true for value types. It didn't take me long to figure out this is due to boxing/unboxing. It didn't take me long either to adjust the code to the following:
public void SetValue( TEnum property, object value )
{
if ( !_properties[ property ].Equals( value ) )
{
// Only come here when the new value is different.
}
}
The thing is I'm not entirely satisfied with this solution. I'd like to keep a simple reference comparison, unless the value is boxed.
The current solution I am thinking of is only calling Equals() for boxed values. Doing a check for a boxed values seems a bit overkill. Isn't there an easier way?
If you need different behaviour when you're dealing with a value-type then you're obviously going to need to perform some kind of test. You don't need an explicit check for boxed value-types, since all value-types will be boxed** due to the parameter being typed as object.
This code should meet your stated criteria: If value is a (boxed) value-type then call the polymorphic Equals method, otherwise use == to test for reference equality.
public void SetValue(TEnum property, object value)
{
bool equal = ((value != null) && value.GetType().IsValueType)
? value.Equals(_properties[property])
: (value == _properties[property]);
if (!equal)
{
// Only come here when the new value is different.
}
}
( ** And, yes, I know that Nullable<T> is a value-type with its own special rules relating to boxing and unboxing, but that's pretty much irrelevant here.)
Equals() is generally the preferred approach.
The default implementation of .Equals() does a simple reference comparison for reference types, so in most cases that's what you'll be getting. Equals() might have been overridden to provide some other behavior, but if someone has overridden .Equals() in a class it's because they want to change the equality semantics for that type, and it's better to let that happen if you don't have a compelling reason not to. Bypassing it by using == can lead to confusion when your class sees two things as different when every other class agrees that they're the same.
Since the input parameter's type is object, you will always get a boxed value inside the method's context.
I think your only chance is to change the method's signature and to write different overloads.
How about this:
if(object.ReferenceEquals(first, second)) { return; }
if(first.Equals(second)) { return; }
// they must differ, right?
Update
I realized this doesn't work as expected for a certain case:
For value types, ReferenceEquals returns false so we fall back to Equals, which behaves as expected.
For reference types where ReferenceEquals returns true, we consider them "same" as expected.
For reference types where ReferenceEquals returns false and Equals returns false, we consider them "different" as expected.
For reference types where ReferenceEquals returns false and Equals returns true, we consider them "same" even though we want "different"
So the lesson is "don't get clever"
I suppose
I'd like to keep a simple reference comparison, unless the value is boxed.
is somewhat equivalent to
If the value is boxed, I'll do a non-"simple reference comparison".
This means the first thing you'll need to do is to check whether the value is boxed or not.
If there exists a method to check whether an object is a boxed value type or not, it should be at least as complex as that "overkill" method you provided the link to unless that is not the simplest way. Nonetheless, there should be a "simplest way" to determine if an object is a boxed value type or not. It's unlikely that this "simplest way" is simpler than simply using the object Equals() method, but I've bookmarked this question to find out just in case.
(not sure if I was logical)

C# Overloading operator ==

//overloading operator ==
class Point
{
private int m_X,int m_Y;
public static operator == (Point p1 ,Point p2)
{
if(object.ReferenceEquals(p1,p2)
return true;
if((object)(p1) == null) || ((object)(p2) ==null)
return false;
return( (p1.x == p2.x) && (p1.x == p2.x));
}
//overloading the != operator
}
Is it necessary to override the Equals function
if the p1 and p2 is not typecasted to object , stack overflow exception is thrown
Why we need to the Point objects to typecast to object.
It is generally a good idea to override the Equals() method if you overload the == operator, because they should return the same result, and Object.Equals() will defer to ReferenceEquals() if you do not override it so the operator and method will have different outcomes. The easy way to do that is to have the operator call the Equals() method (which should have similar code as you have here)
You must cast to Object to perform the == null comparisons, because you're in the overloaded == method, and so without a cast to a base type your operator method is calling itself endlessly to try to evaluate whether p1 == null.
In Guidelines for Overriding Equals() and operator ==, it 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.
1) It is not strictly necessary to overload .Equals(), but it is considered good coding practice to do so. You generally don't want .Equals() to do reference comparisons and operator == to do value comparisions. You should also override GetHashCode and operator!=.
2) The stack overflow occurs because you are calling your own operator== over and over again. The compiler has two choices when the casts are not present:
Use your implementation of operator==(Point, Point)
Use Object's operator==(object, object)
Because #1 is more specific, the compiler chooses your implementation. Explicilty casting both to object ensures that Object's implementation of operator== is called. You could achieve the same thing without the cast with the following code:
if (Object.Equals(p1, null) || Object.Equals(p2, null))
1 - It is not necessary, altough it would be nice. In fact, the behavior you're trying to implement in the operator is commonly put on the Equals method.
2 - If you don't do the cast, p1 == null will call the operator itself, thus causing the stackoverflow.
This link points to the MS guidelines for overriding Equals and ==.
To answer your first question: It's not technically mandatory, but if you don't override Equals, it will do what the == operator originally did: refer back to the System.Object version, which checks to see if the references are the same. So if you want Equals to do the same thing as ==, you have to override that too. Check out "When should I use == and when should I use Equals?" From that article:
For reference types where == has not
been overloaded, it compares whether
two references refer to the same
object - which is exactly what the
implementation of Equals does in
System.Object.
The answer to your second question is that if you don't cast them back to object, there will be an infinitely recursive call to your == operator when you evaluate p1 == null. See it? You'd be calling == inside itself, since p1 is a Point and this is the Point class's == operator. Instead, what you want to do on that line is determine whether the two references are null, which the System.Object version of the operator will do.
As the others have said, it is not strictly necessary to override .Equals(object o) if you create an == operator but it is preferred. In addition, the compiler will generate a couple of warnings if you do not.
warning CS0660: '<Type>' defines operator == or operator != but does not override Object.Equals(object o)
warning CS0661: '<Type>' defines operator == or operator != but does not override Object.GetHashCode()
Thus even the compiler points you towards overriding .Equals(Object o) and having == defer to that.
The stack overflow exception is probably because using == on p1 calls your == operator again, endlessly.
Overriding the == operator in this case is a good idea.
You would benefit from further studying the difference between == and .Equals() as well as the difference between Value and Reference types (Point is a struct, meaning it is a Value type).
Your current override essentially combines reference and value equality checks--making it combine the behaviors of == and .Equals().
Regarding your second question, your == overload calls itself (the == operator is used within the overload). Another aspect to consider is that Point is a value-type, and therefore can never be null (unless it's wrapped in Nullable<Point>).
I agree that overriding == is probably the way to go. But you can clean up a lot of this code by making it a struct instead of a class. You won't have to worry about null checks, and it will make more logical sense since it really is a "value".

C#: How does the static object.Equals check for equality?

Say you have two different classes where each have their own implementation of Equals; which one is used? What if only one of them have one? Or none of them? Are any of the following lines equivalent?
object .Equals( first, second )
first .Equals( second )
second .Equals( first )
I'm guessing that the first two might be equivalent, but I don't really have a clue.
What does it really do?
Basically it does three things:
Check for reference equality (return true if so)
Check for reference nullity (return false if either value is null; by now the null == null case has been handled)
Check for value equality with first.Equals(second)
The ordering shouldn't matter if both values have well-behaved equality implementations, as equality should be implemented such that x.Equals(y) implies y.Equals(x). However, the offline documentation I've got installed does state that first.Equals(second) (or objA.equals(objB) to use the real parameter naming) is specified. The online documentation doesn't mention this, interestingly enough.
Just to make all of this concrete, the implementation could look like this:
public static bool Equals(object x, object y)
{
if (x == y) // Reference equality only; overloaded operators are ignored
{
return true;
}
if (x == null || y == null) // Again, reference checks
{
return false;
}
return x.Equals(y); // Safe as we know x != null.
}
By default, object equivalency is determined by the object's address in memory. If both instances have the same memory address, they are equal.
However, this can be overloaded within the object so that developers can compare two objects that arn't in the same memory location and still be considered equal. For example, if you had a Data Access Layer where each object had its data record's ID from the database, you could have object equality compared based on the ID.
You can overload operators to produce this functionality.

Categories