代码之家  ›  专栏  ›  技术社区  ›  Daniel James Bryars

((system.object)p==空)

  •  5
  • Daniel James Bryars  · 技术社区  · 16 年前

    为什么这样做:

        // If parameter cannot be cast to Point return false.
        TwoDPoint p = obj as TwoDPoint;
        if ((System.Object)p == null)
        {
            return false;
        }
    

    而不是这个:

        // If parameter cannot be cast to Point return false.
        TwoDPoint p = obj as TwoDPoint;
        if (p == null)
        {
            return false;
        }
    

    我不明白你为什么要写((system.object)p)?

    当做,

    丹

    5 回复  |  直到 16 年前
        1
  •  12
  •   Mark Rushakoff    16 年前

    你投到 object 当您不知道或无法确定原始类是否已重写时 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");
            }
        }
    }
    

    此代码输出 只有 "ae is null" 显然不是这样。演员阵容 对象 避免了 AlwaysEqual 班的 运算符== 因此是一个真正的参考检查 null .

        2
  •  1
  •   Å¡ljaker    16 年前

    .NET中的每个对象都是从System.Object派生的,因此不需要显式转换。

        3
  •  1
  •   pdbartlett    16 年前

    更简洁的是:

    if (!(obj is TwoDPoint)) {
      return false;
    }
    
        4
  •  1
  •   Earlz    16 年前

    显然,这是毫无意义的。无论类型如何,都可以始终分配空值(不包括不可为空的值,如int和structs),以便始终检查它。不需要石膏

    如果 TwoDPoint 是不可为空的类型,例如结构,则它确实可以有点。这个 (System.Object) 缓存会有效地将结构装箱到可为空的对象中。但如果是这样的话 obj as TwoDPoint 无效。你需要 obj as TwoDPoint? 使其可以为空。(不能与非空值一起使用)

        5
  •  1
  •   Igor Zevaka    16 年前

    如果代码在里面就完全有意义了 Object.Equals 重写并且不希望调用相等运算符(例如,它可能错误地调用 Equals )强制转换为对象允许调用标准的相等运算符,该运算符比较引用。

    通常,你会使用 Object.ReferenceEquals 将对象的实例与 null 里面 等于 重写。

    例如,这将导致堆栈溢出:

    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;
      }
    }
    

    在上面的示例中,相等运算符调用 等于 因为 otherPoint 变量的类型为 Point ,它将调用相等运算符,导致无限递归。

    通常,当您覆盖 等于 并定义相等运算符,将比较逻辑放入运算符并从 等于 重写。记住,如果两个类都被重写,建议类是不可变的。

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