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”使用直接引用比较。看见