Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ((System.Object)p==null)_C#_Class_Struct_Equals - Fatal编程技术网

C# ((System.Object)p==null)

C# ((System.Object)p==null),c#,class,struct,equals,C#,Class,Struct,Equals,为什么会这样: // 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

为什么会这样:

    // 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)

问候,


简单地说,这是毫无意义的。无论类型如何,都可以始终为Null赋值(非Null值,例如int和structs除外),因此可以始终对其进行检查。演员阵容是不必要的


如果
TwoDPoint
是一个不可为空的类型,例如结构,那么它实际上可能有一个点。
(System.Object)
缓存将有效地将结构装箱到可为空的对象中。但是如果是这样的话,那么作为双点的obj将是无效的。您需要
obj作为TwoDPoint?
使其可为空。(不能与非Nullable一起使用)

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

更简洁的是:

if (!(obj is TwoDPoint)) {
  return false;
}

当您不知道或不能确定原始类是否已重写
运算符==
时,可以强制转换到
对象:

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为空”
,情况显然并非如此。对
对象的强制转换
避免了类的
操作符==
,因此是针对
null
的真正引用检查。如果该代码在
对象内,则完全有意义。等于
重写,并且您不想调用相等操作符(例如,这可能会错误地调用
Equals
)。转换到对象允许调用标准相等运算符,该运算符比较引用

通常,您会使用
Object.ReferenceEquals
将对象实例与
null
内部
Equals
覆盖进行比较

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

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;
  }
}
在上面的示例中,相等运算符调用
Equals
,并且由于
otherPoint
变量的类型为
Point
,它将调用相等运算符,从而导致无限递归

通常,当您重写
Equals
并定义相等运算符时,您会将比较逻辑放在运算符中,并从
Equals
重写中调用该逻辑。请记住,如果同时重写了这两个运算符,则建议类不可变

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

我在等他说这是他的老师说的做这件事的方式:)好吧,但是。。。Earlz,没有。我在仔细检查。这很有趣,为什么他们会在MSDN上给出这样的例子?如果你只是检查
p
是正确的类型,也会更有效。嗯,好的。也许这就是问题的关键,即非空值。我再看一看,谢谢。如果你有时间的话,Dan@Daniel请参阅我的编辑,了解为什么它不是不可为空的问题。至于你的链接。这很奇怪
==
操作符的重载。但是
Equals
函数不是静态的,所以如果它没有指向有效的对象,那么会发生什么呢?这是正确的问题:)酷-是的,花了我一段时间;我明白了,你是对的。谢谢msdn把我弄糊涂了。抱歉。那么,强制转换到(System.Object)将强制调用对象中的“==”?奇怪..在这些情况下,我总是更喜欢
object.ReferenceEquals(obj,null)
语法。它更清楚地说明了代码的意图;但我很想问/研究这个问题(试着简短地重新措辞)“当专家纠正msdn文本时,他们是否应该详细阐述?”。现在,已经加载了,但我得走了……注意:由于c#7,您可以使用“is”操作符检查null。“is”使用直接引用比较。看见