## #421 – Value Equality and IComparable Example

Here’s a full example of a reference type that supports value equality semantics and implements both IEquatable and IComparable.

```    public class Rectangle : IEquatable<Rectangle>, IComparable<Rectangle>
{
public int Height { get; set; }
public int Width { get; set; }

public Rectangle(int height, int width)
{
Height = height;
Width = width;
}

public override bool Equals(object obj)
{
return this.Equals(obj as Rectangle);
}

public override int GetHashCode()
{
return Height.GetHashCode() ^ Width.GetHashCode();
}

public bool Equals(Rectangle r)
{
if (ReferenceEquals(r,null))
return false;

return ((Height == r.Height) && (Width == r.Width) ||
(Height == r.Width) && (Width == r.Height));
}

public static bool operator ==(Rectangle r1, Rectangle r2)
{
if (ReferenceEquals(r1, null))
{
return ReferenceEquals(r2, null) ? true : false;
}

return r1.Equals(r2);
}

public static bool operator !=(Rectangle r1, Rectangle r2)
{
return !(r1 == r2);
}

// Result:
//  < 0 : this instance less than r
//  = 0 : this instance equivalent to r
//  > 0 : this instance greater than r
public int CompareTo(Rectangle r)
{
if (ReferenceEquals(r, null))
return 1;

if (this.Equals(r))
return 0;

else if (this.Area() == r.Area())
return this.Width - r.Width;

else
return this.Area() - r.Area();
}

public static bool operator <(Rectangle r1, Rectangle r2)
{
if (ReferenceEquals(r1, null))
return false;

else
return (r1.CompareTo(r2) < 0) ? true : false;
}

public static bool operator >(Rectangle r1, Rectangle r2)
{
if (ReferenceEquals(r1, null))
return false;

else
return (r1.CompareTo(r2) > 0) ? true : false;
}

public static bool operator <=(Rectangle r1, Rectangle r2)
{
return (r1 < r2) || (r1 == r2);
}

public static bool operator >=(Rectangle r1, Rectangle r2)
{
return (r1 > r2) || (r1 == r2);
}

public int Area()
{
return Height * Width;
}
}
```