为什么这样做:
// 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)?
此致
丹
答案 0 :(得分:12)
当您不知道或无法确定原始课程是否已覆盖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"
,显然不是这种情况。转化为object
会避开AlwaysEqual
类的operator ==
,因此对null
进行真正的参考检查。
答案 1 :(得分:1)
简单地说,这是毫无意义的。无论类型如何,都可以始终指定Null(非整数,例如整数和结构),因此可以始终检查它。演员没有必要
如果TwoDPoint
是一个非可空类型,例如结构,那么它确实可能有一个点。 (System.Object)
缓存会将结构有效地封装成可以为空的对象。但如果是这种情况,则obj as TwoDPoint
将无效。您需要obj as TwoDPoint?
才能使其可以为空。 (不能像非空格一样使用)
答案 2 :(得分:1)
.NET中的每个对象都派生自System.Object,因此不需要显式转换。
答案 3 :(得分:1)
更简洁的是:
if (!(obj is TwoDPoint)) {
return false;
}
答案 4 :(得分:1)
如果代码在Object.Equals
覆盖内,并且您不想调用相等运算符(例如,可能错误地调用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);
}
}