我有Foo
类型的对象
Foo有Id
(int)
a)代码是否“好”?
b)如果两者都为空,我应该返回什么?
// overload operator ==
public static bool operator ==(Foo a, Foo b)
{
if (ReferenceEquals(x, y))
{
return true;
}
if (x == null && y == null)
{
return // ???
}
if (x == null || y == null)
{
return false;
}
return x.Id == y.Id; // Ids are the same
}
public static bool Equals(Foo x, Foo y)
{
return x == y;
}
编辑:
c)等于方法是否应该调用 ==运算符,或者反之?
最后一个问题
d)有可能吗?
ReferenceEquals(x, y) == true
和 x.Id != y.Id
?
答案 0 :(得分:14)
这实际上是无法访问的代码,如果两个操作数均为空,则ReferenceEquals()
为documented以返回true
。
编辑:专门回答您的观点(d):当ReferenceEquals
返回true
时,两个引用必须相同;所以他们指向同一个对象。因此,除非您在属性访问器中执行不可预测的操作,否则将从同一对象读取Id的值,并且期望将是相同的。 (这里的故事的道德是,属性应该以可重复的方式表现,没有其他副作用,如果没有设置,可能会分配一个ID)
完全有可能你有两个具有相同Id
但不同引用的对象。例如:
Foo a = new Foo();
Foo b = new Foo();
比较ReferenceEquals()
和a
(因为它们不同的实例)时, b
会给出错误,但除非该构造函数做了类似分配{{{ 1}},我希望他们分享这个Id,你的平等检查会通过。
答案 1 :(得分:9)
是
null
只是内部指针,其值为零。所以它正在比较两个值为零的引用。
事实上object.ReferenceEquals(null, null)
总是因为这个事实,所以你不需要第二次检查。
if (ReferenceEquals(x, y))
{
return true;
}
if (x == null && y == null) // THIS CHECK IS REDUNDANT!!!
{
return true;
}
最后一点,==和等于处理相同,除非在盒装值类型:
object s1 = 2;
object s2 = 1+1;
Console.WriteLine(s1 == s2);
Console.WriteLine(s1.Equals(s2));
这会产生false
和true
。
点d:否它是同一个对象,相同的内存空间 - 如果它们指向对象上的一个字段。
答案 2 :(得分:4)
null == null
我会像这样重构你的代码
if(x!=null && y!=null)
return x.id == y.id;
return x == null && y == null;
答案 3 :(得分:3)
ReferenceEquals
已经处理了这种情况 - MSDN状态“如果objA与objB是同一个实例,或者两者都是null,则为true;否则为false。”重新评估其回报值。