开发者

((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 do开发者_运维技巧n'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);
  }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜