class Base: IEquatable<Base> {
public Base(int X, int Y) {
public override bool Equals(object obj) {
Console.WriteLine(" Base.Equals(object)");
if (object.ReferenceEquals(this, obj)) return true;
if (obj is null || obj.GetType()!=this.GetType()) return false;
public bool Equals(Base o) { Console.WriteLine(" Base.Equals(Base)"); return object.Equals(this, o); }
public static bool operator ==(Base o1, Base o2) { Console.WriteLine(" Base=="); return object.Equals(o1, o2); }
public static bool operator !=(Base o1, Base o2) { Console.WriteLine(" Base!="); return !object.Equals(o1, o2); }
public override int GetHashCode() => X ^ Y;
class Derived : Base, IEquatable<Derived> {
public Derived(int X, int Y, int Z, int K) : base(X, Y) {
public override bool Equals(object obj) {
Console.WriteLine(" Derived.Equals(object)");
if (object.ReferenceEquals(this, obj)) return true;
if (obj is null || obj.GetType()!=this.GetType()) return false;
public bool Equals(Derived o) { Console.WriteLine(" Derived.Equals(Derived)"); return object.Equals(this, o); }
public override int GetHashCode() => base.GetHashCode() ^ Z ^ K;
public static void Main()
Derived d1 = new Derived(0, 1, 2, 3), d2 = new Derived(0, 1, 4, 5), d3 = new Derived(0, 1, 2, 3), d4 = null;
Base b1 = d1, b2 = d2, b3 = d3, b4 = d4;
Console.WriteLine("d1==d2"); Console.WriteLine(" "+ (d1==d2));
Console.Write("d1.Equals(d2)"); Console.WriteLine(" " + d1.Equals(d2)+"\n");
Console.WriteLine("d1==d3"); Console.WriteLine(" "+ (d1==d3));
Console.Write("d1.Equals(d3)"); Console.WriteLine(" " + d1.Equals(d3)+"\n");
Console.WriteLine("d1==d4"); Console.WriteLine(" "+ (d1==d4));
Console.Write("d1.Equals(d4)"); Console.WriteLine(" " + d1.Equals(d4)+"\n");
Console.WriteLine("b1==b2"); Console.WriteLine(" "+ (b1==b2));
Console.Write("b1.Equals(b2)"); Console.WriteLine(" " + b1.Equals(b2)+"\n");
Console.WriteLine("b1==b3"); Console.WriteLine(" "+ (b1==b3));
Console.Write("b1.Equals(b3)"); Console.WriteLine(" " + b1.Equals(b3)+"\n");
Console.WriteLine("b1==b4"); Console.WriteLine(" "+ (b1==b4));
Console.Write("b1.Equals(b4)"); Console.WriteLine(" " + b1.Equals(b4)+"\n");
Console.WriteLine("b==d1"); Console.WriteLine(" "+ (b==b1));
Console.Write("b.Equals(d1)"); Console.WriteLine(" " + b.Equals(d1)+"\n");