views:

143

answers:

5

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

+1  A: 

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)

Earlz
Hmm okay. Perhaps that's the point, the non-nullables that is. I'll look at it a bit more, thanks. If you have the time - http://msdn.microsoft.com/en-us/library/ms173147(VS.80).aspxRegards,Dan
Daniel Bryars
@Daniel see my edit for why it isn't a non-nullable problem. As for your link though. That is quite curious the overloading of the `==` operator. but the `Equals` function isn't static so if it isn't pointing at a valid object then what happens? That is the correct question :)
Earlz
@Daniel I think @Mark is correct on this one.
Earlz
+1  A: 

Every object in .NET is derived from System.Object so there is no need for explicit cast.

šljaker
Cool - yes, took me a while; you're right, I see. Thanks. The msdn http://msdn.microsoft.com/en-us/library/ms173147(VS.80).aspx confused me. Sorry.
Daniel Bryars
+1  A: 

And even more concise would be:

if (!(obj is TwoDPoint)) {
  return false;
}
pdbartlett
It would also be more efficient if you're just checking that `p` is of the right type.
ChrisF
+10  A: 

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.

Mark Rushakoff
So, casting to ( System.Object ) would force the invocation of "==" in Object? Strange..
OscarRyz
I always prefer the `object.ReferenceEquals(obj, null)` syntax in these situations. It spells out the intention of the code much more clearly.
LukeH
I'm being dragged away; but I'd love to ask/ research the question (try and rephrase shortly) "when an expert corrects the msdn text should they elaborate more?". Now, that's loaded but I gotta go...
Daniel Bryars
+1  A: 

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);
  }
}
Igor Zevaka