Let's say I have a parent class and child class as below
Parent Class:
class Parent
{
public string _First;
public string _Last;
public override bool Equals(object obj)
{
if (ReferenceEquals(obj, null))
return false;
else if (ReferenceEquals(obj, this))
return true;
else if (obj is Parent == false)
return false;
else
return this.Equals(obj as Parent) & base.Equals(obj);
}
public override int GetHashCode()
{
unchecked
{
return this._First.GetHashCode() ^ this._Last.GetHashCode() ^ base.GetHashCode();
}
}
public bool Equals(Parent that)
{
if (ReferenceEquals(that, null))
return false;
else if (ReferenceEquals(that, this))
return true;
else
return this._First.Equals(that._First) & this._Last.Equals(that._Last);
}
public static bool operator ==(Parent p1, Parent p2)
{
return p1.Equals(p2);
}
public static bool operator !=(Parent p1, Parent p2)
{
return !p1.Equals(p2);
}
}
Child Class:
class Child : Parent
{
public string Address;
public override bool Equals(object obj)
{
if (ReferenceEquals(obj, null))
return false;
else if (ReferenceEquals(obj, this))
return true;
else if (obj is Parent == false)
return false;
else
return this.Equals(obj as Child);
}
public override int GetHashCode()
{
unchecked
{
return this._First.GetHashCode() ^ this._Last.GetHashCode() ^ base.GetHashCode();
}
}
public bool Equals(Child that)
{
if (ReferenceEquals(that, null))
return false;
else if (ReferenceEquals(that, this))
return true;
else
return this.Address.Equals(that.Address) & base.Equals(that);
}
public static bool operator ==(Child p1,Child p2)
{
return p1.Equals(p2);
}
public static bool operator !=(Child p1, Child p2)
{
return !p1.Equals(p2);
}
}
And here is the code to compare two instances of child.
Parent p = new Child() { _First = "Mitul", _Last = "Patel", Address="abc1"};
Parent p1 = new Child() { _First = "Mitul", _Last = "Patel", Address = "abc" };
Child c = new Child() { _First = "Mitul", _Last = "Patel", Address = "abc1" };
Child c1 = new Child() { _First = "Mitul", _Last = "Patel", Address = "abc" };
Console.WriteLine(p.Equals(p1));
Console.WriteLine(p == p1);
Console.WriteLine(c.Equals(c1));
Console.WriteLine(c == c1);
Console.Read();
Output
True True False False
I know why it gives true and true during first comparison. Because it calls the overloaded ==() operator of parent class. My question is I wanted to use == operator of child class because the object is of type Child so how can it be possible? For static methods virtual keyword can not be used.
Thanks,
All overloaded operators except assignment (operator=) are inherited by derived classes. The first argument for member-function overloaded operators is always of the class type of the object for which the operator is invoked (the class in which the operator is declared, or a class derived from that class).
In the inheritance hierarchy, superclass and subclass methods can be overridden and overloaded.
This means C++ has the ability to provide the operators with a special meaning for a data type, this ability is known as operator overloading. For example, we can overload an operator '+' in a class like String so that we can concatenate two strings by just using +.
C does not support operator overloading (beyond what it built into the language).
The implementation of the operator is chosen at compile time. Operators are not virtual methods- the child class's ==
operator does not override the parent class ==
operator.
Therefore the only way to make the compiler select the child ==
operator is to have the variables themselves be of type Child
, e.g.
Child p = new Child() { _First = "Mitul", _Last = "Patel", Address="abc1"};
Child p1 = new Child() { _First = "Mitul", _Last = "Patel", Address = "abc" };
or to have the ==
operator call the Equals method, and make the Child implementation of Equals override the parent implementation:
in Parent.cs:
// No need for these to be public- they should only be called internally.
protected virtual bool Equals(Parent that)
{
if (ReferenceEquals(that, null))
return false;
else if (ReferenceEquals(that, this))
return true;
else
return this._First.Equals(that._First) & this._Last.Equals(that._Last);
}
in Child.cs:
// Notice I changed your argument type here...
protected override bool Equals(Parent that)
{
// If we are not dealing with a Child instance, delegate to the base class.
if (!(that is typeof(Child)))
return base.Equals(that);
if (ReferenceEquals(that, null))
return false;
else if (ReferenceEquals(that, this))
return true;
else
return this.Address.Equals(that.Address) & base.Equals(that);
}
static
methods are resolved at compile time, not at run time.
For your code p
and p1
are Parent
objects, so it will call the ==
operator of the Parent
class.
If you want the operator of the derived class to be called, you must declare them as derived class instances.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With