Say you were writing the original C# Object
class and you wanted the following functionality:
object1 == object2
will compare references unless this operator is overriddenobject1 != object2
will always return the inverse of the object's ACTUALobject1 == object2
So, for example, if I have a Bunny
class (derived from Object
) which uses ear lengths as its equals method, then the notequals method (inherited from Object
) should return true if the bunnies have different ear lengths.
The problem that I see is that if I write my Object
class something like:
public partial class Object {
public virtual bool Equals(Object o2) {
return (this === o2);
}
public bool NotEquals(Object o2) {
return !this.Equals(o2);
}
}
then it seems like that definition will bind NotEquals to Object
's Equals, not the actu开发者_Go百科al derived class's equals.
Is there some way that this can work without modifying C# itself in any way? I don't care so much that it's possible in C# but I care if there's some OOP principle which tells me that I shouldn't expect this sort of thing to work.
Also, I'm not sure whether or not this is fundamental to the question, but the idea is for NotEquals to be virtual as well so that it too can be overridden by derived classes which want their o1 != o2
to be different from !(o1 == o2)
. This question is inspired by this recent discussion.
The code you've provided will call the derived Equals
method. Equals
is virtual, and that means that when it is called, the "most derived" implementation will be used.
NotEquals will not bind to the Object class's equal method, it will use the most derived method. You could've easily tested this. And it's also easy to make notEquals virtual, so you could override that with custom logic as well.
Using these classes (ignore the horrible naming conventions):
class parent
{
public virtual bool equals(parent p)
{
Console.WriteLine("parent equals");
return false;
}
public virtual bool notEquals(parent p)
{
return !this.equals(p);
}
}
class child : parent
{
public override bool equals(parent p)
{
Console.WriteLine("child equals");
return true;
}
}
Then running this:
parent p = new parent();
p.notEquals(null);
child c = new child();
c.notEquals(null);
Results in this output:
parent equals
child equals
I might be misunderstanding the question, but the NotEquals
method declared in Object
in your example will use the Equals
method defined on the derived class (if it is declared with the override modifier in the derived class), not on Object
itself.
Take this simple example that demonstrates this behavior:
void Main()
{
BaseObject do1 = new DerivedObject();
BaseObject do2 = new DerivedObject();
do1.NotEquals(do2);
}
public class DerivedObject : BaseObject
{
public override bool Equals(BaseObject o2)
{
Console.WriteLine("OtherObject.Equals called.");
return (this == o2);
}
}
public partial class BaseObject {
public virtual bool Equals(BaseObject o2) {
return (this == o2);
}
public bool NotEquals(BaseObject o2) {
return !this.Equals(o2);
}
}
If you execute that example you'll see that the Console.WriteLine statement is executed (take away the override modifier on DerivedObject, and then the Console.WriteLine will not be executed).
You can also view the documentation, which states: "The overriding member in the most derived class is called, which might be the original member, if no derived class has overridden the member.".
It's not entirely clear what you're trying to ask because you can't change the definition of Object
so the exercise is somewhat moot, but pretending that you can and are actually changing the Object
class, this.Equals
would in fact refer to the derived class's implementation because the Equals
is virtual.
In particular I'm not sure what you mean by "this" in your sentence:
"Is there some way that this can work without modifying C# itself in any way?"
精彩评论