I want to overload the the comparison operator (==) in Dart to compare structures. Now I'm not sure how to do this for derived classes when I already have overloaded the comparison operator of the base class and want to reuse that.
Assuming I have a a base class like:
class Base
{
int _a;
String _b;
bool operator ==(Base other)
{
if (identical(other, this)) return true;
if (_a != other._a) return false;
if (_b != other._b) return false;
return true;
}
}
Then I declare I derived class that adds additional fields and also want to overload operator==. I only want to compare the additional fields in the derived class and delegate the comparison of Base fields to the Base class. In other programming languages I could do something like Base::operator==(other)
or super.equals(other)
, but in Dart I can't figure out what's the best way to do it.
class Derived extends Base
{
int _c; // additional field
bool operator ==(Derived other)
{
if (identical(other, this)) return true;
if (_c != other._c) return false; // Comparison of new field
// The following approach gives the compiler error:
// Equality expression cannot be operand of another equality expression.
if (!(super.==(other))) return false;
// The following produces "Unnecessary cast" warnings
// It also only recursively calls the Derived operator
if ((this as Base) != (other as Base)) return false;
return true;
}
}
I guess what I could do is:
equals
function with the same logic as currently operator ==
in it, call super.equals()
to compare the base class and delegate all calls of operator==
to the equals
function. However it doesn't look too appealing to implement equals
and operator ==
.So what's the best or recommended solution for this problem?
Ok, after some further experiments I figured it out on my own. It's simply calling:
super==(other)
I tried it with super.operator==(other)
and super.==(other)
before, but didn't expect that the simple super==(other)
is sufficient.
For the given example above the correct operator is:
bool operator ==(Derived other)
{
if (identical(other, this)) return true;
if (_c != other._c) return false;
if (!(super==(other))) return false;
return true;
}
Seems I am bumping a 5 year old question, but since now we have Dart 2...
the == operator can easily be defined inline.
class Base {
int a;
String b;
bool operator ==(other) => other is Base
&& other.a == a
&& other.b == b;
}
To reuse from a derived class, super == other
still seems to be the way.
class Derived extends Base {
int c;
bool operator ==(other) => other is Derived
&& super == other
&& other.c == c;
}
Now this being said I discovered a major gotcha, the == operator that is called seems to be that of the left side of the comparision. That is Base == Derived
will call Base's == comparision, while Derived == Base
will call call Derived's == comparison (and subsequently Base's). This does seem reasonable, but had me scratching my head for a minute.
Ex:
main() {
Base b = new Base();
Derived d1 = new Derived();
Derived d2 = new Derived();
b.a = 6;
d1.a = 6;
d2.a = 6;
b.b = "Hi";
d1.b = "Hi";
d2.b = "Hi";
d1.c = 1;
d2.c = 1;
assert(d1 == d2); // pass
assert(b == d1); // PASS!!!
assert(d1 == b); // fail
}
(Note: I removed the private _'s from the fields for demonstration purposes.)
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