Why cast null before checking if object is equal to null? - c#

I was looking through the "Domain Oriented N-Layered .NET 4.0 Sample App" project and ran across some code that I do not understand. In this project they often use syntax like the following to check arguments for null:
public GenericRepository(IQueryableContext context,ITraceManager traceManager)
{
if (context == (IQueryableContext)null)
throw new ArgumentNullException("context", Resources.Messages.exception_ContainerCannotBeNull);
Why would you cast null to the type of the object you are checking for null?

It's pointless in the example given.
While not applicable in this case, there is sometimes a need to cast null (or at least there was before default(T) was added. Consider the following:
void DoSomething(string x) {
...
}
void DoSomething(object x) {
...
}
DoSomething(null); // compiler can't infer the type
DoSomething((string)null); // string type is now explicit
DoSomething(default(string)); // same as previous
EDIT
Just thought of another case where you would have to do the cast when testing equality. If you had an object that had an overloaded == operator that allowed comparison with two reference types, comparing against null would be ambiguous. However because IQueryableContext is most likely an interface and interfaces cannot overload the == operator, I still don't see any valid reason to do it in the example you gave.
class CustomObject {
private string _id;
public CustomObject(string id) {
_id=id;
}
public static bool operator ==(CustomObject lhs, CustomObject rhs) {
if (ReferenceEquals(lhs, rhs)) { return true; }
if (ReferenceEquals(lhs, null)) { return false; }
if (ReferenceEquals(rhs, null)) { return false; }
return lhs._id == rhs._id;
}
public static bool operator !=(CustomObject lhs, CustomObject rhs) {
return !(lhs == rhs);
}
public static bool operator ==(CustomObject lhs, string rhs) {
if (ReferenceEquals(lhs, rhs)) { return true; }
if (ReferenceEquals(lhs, null)) { return false; }
if (ReferenceEquals(rhs, null)) { return false; }
return lhs._id == rhs;
}
public static bool operator !=(CustomObject lhs, string rhs) {
return !(lhs==rhs);
}
}
CustomObject o = null;
if (o == null) {
Console.WriteLine("I don't compile.");
}

I wouldn't do a cast. There's no reason for it in this case.

There is no reason to cast null in the given example. It might be for legibility... I don't know, I wouldn't do this =P
In some cases [which doesn't include the case covered in this topic] you have to cast to INullable before you can check to see if a variable is null. Otherwise, you have to use object==default(TypeOfObject)...

Related

How to perform a null check in an equality operator overload

I've written a simple class that wraps an XElement. I want to pass through equality operations to the wrapped instance. So I wrote this:
public class XmlWrapper
{
protected readonly XElement _element;
public XmlWrapper(XElement element)
{
_element = element;
}
static public bool operator == (XmlWrapper lhs, XmlWrapper rhs)
{
return lhs._element.Equals(rhs._element);
}
static public bool operator != (XmlWrapper lhs, XmlWrapper rhs)
{
return !(lhs == rhs);
}
}
This seems straightforward, but actually it throws an exception for a very simple null check:
XmlWrapper wrapper = new XmlWrapper(someElement);
XmlWrapper nullWrapper = null;
if (wrapper != nullWrapper) Console.WriteLine("Wrapper is not null"); //This line throws
It's because the equality operator is receiving null for one of its arguments and therefore can't retrieve the wrapped XElement. So the obvious thought is to add a null check, like this:
static public bool operator == (XmlWrapper lhs, XmlWrapper rhs)
{
if (lhs == null && rhs == null) return true;
if (lhs == null || rhs == null) return false;
return lhs._element.Equals(rhs._element);
}
However, this results infinite recursion, because the == operator calls the == operator again.
If this were any other kind of method, I'd just call the base, but that doesn't work with an operator, e.g. you can't write
if (lhs base.== rhs)
So how do I get around this? Is there some way to call the base == operator from within the overloaded operator body? Or some other way to perform the null check without using ==?
Here is the code on DotNetFiddle.
public static bool operator == (XmlWrapper lhs, XmlWrapper rhs)
{
if (Object.ReferenceEquals(lhs, null) && Object.ReferenceEquals(rhs, null))
{
return true;
}
if (Object.ReferenceEquals(lhs, null) || Object.ReferenceEquals(rhs, null))
{
return false;
}
return lhs._element.Equals(rhs._element);
}
This should provide the desired behavior.
Also note that if overriding equality you need to override GetHashCode
public class XmlWrapper : IEquatable<XmlWrapper> {
protected readonly XElement _element;
public XmlWrapper(XElement element) {
_element = element ?? throw new ArgumentNullException(nameof(element));
}
static public bool operator ==(XmlWrapper lhs, XmlWrapper rhs) {
return Equals(lhs, rhs);
}
static public bool operator !=(XmlWrapper lhs, XmlWrapper rhs) {
return !Equals(lhs, rhs);
}
public override string ToString() {
return _element != null ? _element.ToString() : this.GetType().FullName;
}
public override int GetHashCode() {
return _element.GetHashCode();
}
public override bool Equals(object obj) {
return obj is XmlWrapper other && Equals(other);
}
public bool Equals(XmlWrapper other) {
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return _element.Equals(other._element);
}
}
It is worth noting this implementation is specific to reference types. Since XmlWrapper is a reference type.
You can shorten the code down to one line using the ternary operator:
static public bool operator == (XmlWrapper lhs, XmlWrapper rhs)
{
return lhs is null ? rhs is null : !(rhs is null) && lhs._element == rhs._element;
}
Which says, "if lhs is null, return true if rhs is null or false if rhs is not null. Otherwise (if lhs is not null), return true if rhs is not null and their elements are equals, else return false."
You can apply Elvis operator and null-coalescing operator as well to make it working.
static public bool operator == (XmlWrapper lhs, XmlWrapper rhs)
{
if (lhs?._element == null && rhs?._element == null) return true;
return lhs?._element?.Equals(rhs?._element) ?? false;
}

Implicit cast dynamic to DateTime? and op_Equality

I have my own dynamic object which have to be comparable with primitive types. I defined implicit cast operators for all types I want to compare. For most of primitive types like int, short, bool, decimal implementing cast to nullable version of this types is enough for successful comparing, but not for DateTime. Did I missed some significant difference between DateTime and decimal or is it error in dynamic implementation?
class MyDynamic : DynamicObject
{
public static implicit operator decimal?(MyDynamic nullable)
{
return null;
}
public static implicit operator DateTime?(MyDynamic x)
{
return null;
}
//public static implicit operator DateTime(MyDynamic x)
//{
// return DateTime.MinValue;
//}
}
[Fact]
public void FactMethodName()
{
dynamic my = new MyDynamic();
dynamic date = DateTime.Now;
dynamic dec = 1m;
Assert.False(dec == my);
// throws
Assert.False(date == my);
}
If implicit cast is not defined error message is:
System.InvalidOperationExceptionThe operands for operator 'Equal' do not match the parameters of method 'op_Equality'.
stack trace is:
System.InvalidOperationExceptionThe operands for operator 'Equal' do not match the parameters of method 'op_Equality'.
at System.Linq.Expressions.Expression.GetMethodBasedBinaryOperator(ExpressionType binaryType, Expression left, Expression right, MethodInfo method, Boolean liftToNull)
at System.Linq.Expressions.Expression.Equal(Expression left, Expression right, Boolean liftToNull, MethodInfo method)
at Microsoft.CSharp.RuntimeBinder.ExpressionTreeCallRewriter.GenerateUserDefinedBinaryOperator(EXPRCALL pExpr)
at Microsoft.CSharp.RuntimeBinder.ExpressionTreeCallRewriter.VisitCALL(EXPRCALL pExpr)
at Microsoft.CSharp.RuntimeBinder.Semantics.ExprVisitorBase.Dispatch(EXPR pExpr)
at Microsoft.CSharp.RuntimeBinder.Semantics.ExprVisitorBase.Visit(EXPR pExpr)
at Microsoft.CSharp.RuntimeBinder.ExpressionTreeCallRewriter.GenerateLambda(EXPRCALL pExpr)
at Microsoft.CSharp.RuntimeBinder.ExpressionTreeCallRewriter.VisitCALL(EXPRCALL pExpr)
at Microsoft.CSharp.RuntimeBinder.Semantics.ExprVisitorBase.Dispatch(EXPR pExpr)
at Microsoft.CSharp.RuntimeBinder.Semantics.ExprVisitorBase.Visit(EXPR pExpr)
at Microsoft.CSharp.RuntimeBinder.ExpressionTreeCallRewriter.Rewrite(TypeManager typeManager, EXPR pExpr, IEnumerable`1 listOfParameters)
at Microsoft.CSharp.RuntimeBinder.RuntimeBinder.CreateExpressionTreeFromResult(IEnumerable`1 parameters, ArgumentObject[] arguments, Scope pScope, EXPR pResult)
at Microsoft.CSharp.RuntimeBinder.RuntimeBinder.BindCore(DynamicMetaObjectBinder payload, IEnumerable`1 parameters, DynamicMetaObject[] args, ref DynamicMetaObject deferredBinding)
at Microsoft.CSharp.RuntimeBinder.RuntimeBinder.Bind(DynamicMetaObjectBinder payload, IEnumerable`1 parameters, DynamicMetaObject[] args, ref DynamicMetaObject deferredBinding)
at Microsoft.CSharp.RuntimeBinder.BinderHelper.Bind(DynamicMetaObjectBinder action, RuntimeBinder binder, IEnumerable`1 args, IEnumerable`1 arginfos, DynamicMetaObject onBindingError)
at Microsoft.CSharp.RuntimeBinder.CSharpBinaryOperationBinder.FallbackBinaryOperation(DynamicMetaObject target, DynamicMetaObject arg, DynamicMetaObject errorSuggestion)
at System.Dynamic.BinaryOperationBinder.FallbackBinaryOperation(DynamicMetaObject target, DynamicMetaObject arg)
at System.Dynamic.DynamicMetaObject.BindBinaryOperation(BinaryOperationBinder binder, DynamicMetaObject arg)
at System.Dynamic.BinaryOperationBinder.Bind(DynamicMetaObject target, DynamicMetaObject[] args)
at System.Dynamic.DynamicMetaObjectBinder.Bind(Object[] args, ReadOnlyCollection`1 parameters, LabelTarget returnLabel)
at System.Runtime.CompilerServices.CallSiteBinder.BindCore(CallSite`1 site, Object[] args)
at System.Dynamic.UpdateDelegates.UpdateAndExecute2<T0,T1,TRet>(CallSite site, T0 arg0, T1 arg1)
In most cases my custom dynamic should act almost as null, so casting to value type is unwanted.
defining operator == keep code simpler.
public static bool operator ==(MyDynamic lhs, object rhs)
{
if (rhs is MyDynamic)
return lhs.Equals(rhs);
else
return false;
}
public static bool operator !=(MyDynamic lhs, object rhs)
{
if (rhs is MyDynamic)
return !lhs.Equals(rhs);
else
return true;
}
public static bool operator ==(object lhs, MyDynamic rhs)
{
if (lhs is MyDynamic)
return lhs.Equals(rhs);
else
return false;
}
public static bool operator !=(object lhs, MyDynamic rhs)
{
if (lhs is MyDynamic)
return !lhs.Equals(rhs);
else
return true;
}
EDIT
I explicitly implement both (MyDynamic == object) and (object == MyDynamic). because overriding TryBinaryOperation() couldn't caught (object == MyDynamic) case.
public override bool TryBinaryOperation(BinaryOperationBinder binder, object arg, out object result)
{
if (binder.Operation == System.Linq.Expressions.ExpressionType.Equal) { ... }
return base.TryBinaryOperation(binder, arg, out result);
}

Implementing == operator in C# on explicit-interface implementation

I have defined a struct Coords that explicitly implements three interfaces, each defined like this:
public partial struct Coords
{
int ICoordsUser.X { get { return VectorUser.X; } }
int ICoordsUser.Y { get { return VectorUser.Y; } }
IntVector2D ICoordsUser.Vector { get { return VectorUser; }
set { VectorUser=value; } }
ICoordsCanon ICoordsUser.Canon { get { return this; } }
ICoordsUser ICoordsUser.Clone() { return NewUserCoords(VectorUser); }
string ICoordsUser.ToString() { return VectorUser.ToString(); }
IEnumerable<NeighbourCoords> ICoordsUser.GetNeighbours(Hexside hexsides) {
return GetNeighbours(hexsides);
}
int ICoordsUser.Range(ICoordsUser coords) { return Range(coords.Canon); }
}
with the names ICoordsCanon, ICoordsUser, and ICoordsCustom. Then I have defined Value Equality on the struct like so:
#region Value Equality
bool IEquatable<Coords>.Equals(Coords rhs) { return this == rhs; }
public override bool Equals(object rhs) {
return (rhs is Coords) && this == (Coords)rhs;
}
public static bool operator == (Coords lhs, Coords rhs) {
return lhs.VectorCanon == rhs.VectorCanon;
}
public static bool operator != (Coords lhs, Coords rhs) { return ! (lhs == rhs); }
public override int GetHashCode() { return VectorUser.GetHashCode(); }
bool IEqualityComparer<Coords>.Equals(Coords lhs, Coords rhs) { return lhs == rhs; }
int IEqualityComparer<Coords>.GetHashCode(Coords coords) {
return coords.GetHashCode();
}
#endregion
However, when I perform an equality comparison with the == operator between values of one of the interface types, as
if (coordsUser1 == userCoords2) { /* whatever */ }
a reference comparison using object.== is always performed. Does anyone know how I can force value equality onto the == operator in such a circumstance, using C#?
Thank you in advance for any thoughts or suggestions.
[Edit]
In the example above, both coordsUser1 and userCoords2 are instances of Coords stored in variables of type ICoordsUser, so it is not clear to me why the defined override of == is not being used.
Since you cannot define static members for an interface, you cannot define operators on an interface. Because operator overloading is resolved at compile-time, the compiler will not see any == operator that matches the signature given an interface type. Since Object defines the == operator for objects, and there is no better match at compile time, it will use that one.
There are three ways to solve this:
Cast the left-hand object to the type that defines the == operator.
return (Coords)coordsUser1 == userCoords2;
Use the normal Equals(object) method. However, this will box your struct.
return coordsUser1.Equals(userCoords2);
Force your interfaces to implement IEquatable<T>, and use the generic Equals(T) (which reduces boxing).
return coordsUser1.Equals(userCoords2);

((System.Object)p == null)

Why do this:
// If parameter cannot be cast to Point return false.
TwoDPoint p = obj as TwoDPoint;
if ((System.Object)p == null)
{
return false;
}
Instead of this:
// If parameter cannot be cast to Point return false.
TwoDPoint p = obj as TwoDPoint;
if (p == null)
{
return false;
}
I don't understand why you'd ever write ((System.Object)p)?
Regards,
Dan
You cast to object when you don't know or can't be sure whether the original class has overridden operator ==:
using System;
class AlwaysEqual
{
public static bool operator ==(AlwaysEqual a, AlwaysEqual b)
{
return true;
}
public static bool operator !=(AlwaysEqual a, AlwaysEqual b)
{
return true;
}
}
class Program
{
static void Main()
{
object o = new AlwaysEqual();
AlwaysEqual ae = o as AlwaysEqual;
if (ae == null)
{
Console.WriteLine("ae is null");
}
if ((object)ae == null)
{
Console.WriteLine("(object)ae is null");
}
}
}
This code outputs only "ae is null", which is obviously not the case. The cast to object avoids the AlwaysEqual class's operator == and is therefore a true reference check against null.
Every object in .NET is derived from System.Object so there is no need for explicit cast.
And even more concise would be:
if (!(obj is TwoDPoint)) {
return false;
}
Plainly speaking, It's pointless. Null can always be assigned(except for non-nullables such as ints and structs) regardless of type so it can always be checked for. The cast is not necessary
If TwoDPoint is a non-nullable type such as a struct then indeed it may have a point. The (System.Object) cache would effectively box the struct into a nullable object. But if that was the case then obj as TwoDPoint would not be valid. You would need obj as TwoDPoint? to make it nullable. (can't use as with non-nullables)
It makes total sense if that code is inside Object.Equals override and you don't want to invoke the equality operator (which might, for example, erroneously call Equals). Casting to object allows to call standard equality operator, which compares references.
Normally, you would use Object.ReferenceEquals to compare an instance of an object to null inside Equals override.
For example, this would cause a stack overflow:
public class Point {
public override bool Equals (object other) {
var otherPoint = other as Point;
if (other == null)
return false;
//...
}
public static bool operator == (Point l, Point r) {
//...
//null checks
if (!l.Equals(r))
return false;
}
}
In the above example equality operator calls Equals and because otherPoint variable is of type Point, it would invoke the equality operator, causing infinite recursion.
Normally, when you override Equals and define the equality operator, you would put the comparison logic in the operator and invoke that from the Equals override. Bear in mind that it's recommended for the class to be immutable if both are overridden.
public class Point {
public override bool Equals (object other) {
var otherPoint = other as Point;
return this == otherPoint;
}
//must override GetHashCode() as well
public static bool operator == (Point l, Point r) {
if (Object.ReferenceEquals(l, null) && Object.ReferenceEquals(r, null))
return true;
if (Object.ReferenceEquals(l, null) || Object.ReferenceEquals(r, null))
return false;
//actual equality checks
}
public static bool operator != (Point l, Point r) {
return !(l==r);
}
}

overload == (and != , of course) operator, can I bypass == to determine whether the object is null

when I try to overload operator == and != in C#, and override Equal as recommended, I found I have no way to distinguish a normal object and null. For example, I defined a class Complex.
public static bool operator ==(Complex lhs, Complex rhs)
{
return lhs.Equals(rhs);
}
public static bool operator !=(Complex lhs, Complex rhs)
{
return !lhs.Equals(rhs);
}
public override bool Equals(object obj)
{
if (obj is Complex)
{
return (((Complex)obj).Real == this.Real &&
((Complex)obj).Imaginary == this.Imaginary);
}
else
{
return false;
}
}
But when I want to use
if (temp == null)
When temp is really null, some exception happens. And I can't use == to determine whether the lhs is null, which will cause infinite loop.
What should I do in this situation.
One way I can think of is to us some thing like Class.Equal(object, object) (if it exists) to bypass the == when I do the check.
What is the normal way to solve the problem?
Thank you.
You can use the following at the top of your Equals override:
if (Object.ReferenceEquals(obj, null))
return false;
The exception you are getting is probably a StackOverflowException because your == operator will cause infinite recursion.
EDIT:
If Complex is a struct you should not have any problems with NullReferenceExceptions. If Complex is a class you can change your implementation of the == and != operator overloads to avoid the exception (Laurent Etiemble already pointed this out in his answer):
public static bool operator ==(Complex lhs, Complex rhs)
{
return Equals(lhs, rhs);
}
public static bool operator !=(Complex lhs, Complex rhs)
{
return !Equals(lhs, rhs);
}
You should consider using the static Equals method in the operator overloads (which will call the instance Equals method):
public static bool operator ==(Complex lhs, Complex rhs)
{
return Equals(lhs, rhs);
}
public static bool operator !=(Complex lhs, Complex rhs)
{
return !Equals(lhs, rhs);
}
Note: You may also check for null in the Equals method.
You can also read the Object.Equals Topic on MSDN, which is a great source of samples.
public static bool operator ==(Complex lhs, Complex rhs)
{
if (Object.ReferenceEquals(lhs, null))
{
return Object.ReferenceEquals(rhs, null);
}
return lhs.Equals(rhs);
}
public static bool operator !=(Complex lhs, Complex rhs)
{
return !(lhs == rhs);
}
Poor man's unit test
Action<Complex, Complex> tester = (left, right) =>
{
Console.WriteLine(left == right);
Console.WriteLine(left != right);
Console.WriteLine(left == null);
Console.WriteLine(left != null);
Console.WriteLine("---");
};
tester(new Complex(), new Complex());
tester(null, new Complex());
tester(null, null);
tester(new Complex(), null);
I think you shoud test for null in the == operator implementation. Otherwise, when lhs is null, you'd call Complex(null).Equals (I don't know for C#, but in Java this would be a Nullpointer Exception)
To test for null, I suggest something like:
if (null == lhs && null == rhs) return true
else if (null == lhs) return false
else return lhs.Equals(rhs);
So Object.Equals will be called for all == comparisons above.
There is a better approach then using operators is and cast:
Complex c = obj as Complex;
return (c != null) && (c.Real == this.Real) && (c.Imaginary == this.Imaginary);
Here is a quick test concerning Equals operator override and comparing with null:
class Complex
{
public override bool Equals(object obj)
{
if (obj is Complex)
{
return true;
}
else
{
return false;
}
}
}
Debugging doesn't step into operator's body:
var b = (new Complex() == new Complex());

Categories

Resources