问题
I have an object of type Foo
.
Foo has an Id
(int)
a) Is the code bellow "good"?
b) What should I return if both are null?
// 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;
}
EDIT:
c) Should the Equals method call the == operator, or viceversa?
Last question
d) Is it possible that
ReferenceEquals(x, y) == true
AND x.Id != y.Id
?
回答1:
Yes
null
is nothing but internal Pointer with value zero. So it is comparing two references having value zero.
In fact object.ReferenceEquals(null, null)
is always true because of this fact so you do not need the second check.
if (ReferenceEquals(x, y))
{
return true;
}
if (x == null && y == null) // THIS CHECK IS REDUNDANT!!!
{
return true;
}
On the last point, == and Equals are handled the same unless on the boxed value types:
object s1 = 2;
object s2 = 1+1;
Console.WriteLine(s1 == s2);
Console.WriteLine(s1.Equals(s2));
This produces false
and true
.
Point d: NO it is the same object, the same memory space - if they are pointing to a field on the object.
回答2:
That is actually unreachable code, as ReferenceEquals()
is documented to return true
if both operands are null.
EDIT: To specifically answer your point (d): When ReferenceEquals
returns true
, then the two references must be the same; so they point to the same object. So, unless you're doing something unpredictable in the property accessor, the values for the Id will be read from the same object, and would be expected to be the same. (Moral of the story here is that properties should behave in a repeatable manner without other side effects like maybe allocating an Id if none is already set)
It is perfectly possible that you could have two objects with the same Id
, but different references. For example:
Foo a = new Foo();
Foo b = new Foo();
ReferenceEquals()
would give false when comparing a
and b
(as they are different instances), but unless that constructor did anything like allocate an Id
, I'd expect them to share that Id and your equality check would pass.
回答3:
yes,
null == null
I would refactor your code like this
if(x!=null && y!=null)
return x.id == y.id;
return x == null && y == null;
回答4:
ReferenceEquals
already handles the case when both arguments are null — MSDN states "true if objA is the same instance as objB or if both are null; otherwise, false." regarting its return value.
来源:https://stackoverflow.com/questions/4077418/does-null-null