Akshita
Akshita

Reputation: 867

IComparable Implementation

i have written the following code

 class Program
{
    static void Main(string[] args)
    {
        Circle c1 = new Circle(5);
        Circle c2 = new Circle(10);
        Console.WriteLine(c1.Area().ToString());
        if (c1>c2)
        {
        }
    }
}
public class Circle:System.IComparable<Circle>,IComparable
{
    public int radius { get;private set; }
    public double Area()
    {
        return Math.PI * radius * radius;
    }
    public Circle(int radius)
    {
        this.radius = radius;
    }
    public int CompareTo(Circle c)
    {
        if (c.Area() == this.Area())
            return 0;
        if (c.Area() > this.Area())
            return 1;
        return -1;
    }
    public int CompareTo(Object c)
    {
        if (((Circle)c).Area() == this.Area())
            return 0;
        if (((Circle)c).Area() > this.Area())
            return 1;
        return -1;
    }
}

However it the error Error 1 Operator '>' cannot be applied to operands of type 'ConsoleApplication1.Circle' and 'ConsoleApplication1.Circle'

i have implemented both the methods and could not figure the error

Upvotes: 0

Views: 301

Answers (6)

user1429080
user1429080

Reputation: 9166

Implementing IComparable does not by itself create the >, >=, <, <= operators for the class. If you want those operators to be usable with you class, you have to implement them:

public static bool operator > (Circle x, Circle y) {
   return x.CompareTo(y) > 0;
}

// and so on for the other operators

If you decide to create these operators, you might also want to overload the .Equals method and the == operator so that your Circle object will in practise exhibit value type behavior under comparison operations.

Also, since the Area is directly proportional to the radius, you might to well to compare radiuses (? spelling) instead of areas.

Upvotes: 1

Atif Aziz
Atif Aziz

Reputation: 36618

Implementing IComparable or IComparable<T> does not automatically enable the use of comparison operators. You have to specifically provide their implementation. Most of the other answers (at the time of this answer) provide incorrect or incomplete implementations of the operators.

You will need to begin by fixing your CompareTo implementations. The first fix is to make sure you handle null cases. An object always compares greater than null per specifications (see docs):

public int CompareTo(Circle c)
{
    return c == null ? 1 : CompareAreas(this.Area(), c.Area());
}
public int CompareAreas(double a, double b)
{
    return a > b ? 1 : a == b ? 0 : -1;
}

The non-generic version of CompareTo also needs to handle comparison with null and otherwise making sure that it is being indeed compared to a Circle object:

public int CompareTo(Object obj)
{
    if (obj == null) return 1;
    var c = obj as Circle;
    if (c == null) throw new ArgumentException(null, "obj");
    return CompareTo(c); // delegate to CompareTo(Circle)
}

Finally, the > and < operator implementations need to account for one or both sides being null:

public static bool operator >(Circle a, Circle b)
{
    return Compare(a, b) > 0;
}
public static bool operator <(Circle a, Circle b)
{
    return Compare(a, b) < 0;
}
public static int Compare(Circle a, Circle b)
{
    return a == null && b == null ? 0 : a == null ? 1 : a.CompareTo(b);
}

Upvotes: 3

Dave
Dave

Reputation: 3621

You'd need to overload the > operator to do what you're trying:

  public static bool operator > (Circle c1, Circle c2)
  {
     return (c1.CompareTo(C2) > 0);
  }  

Upvotes: 6

Jerry
Jerry

Reputation: 435

The problems in your code:
(1) You should override operator > to use it with 2 Circle objects.
(2) In the compare method, you should return a value indicating the distance between the to Circle objects rather than just 1 or -1 or 0 .
(3) You should call Area() method once and save its value, then use this value when needed rather than all this method every time when you need.

public class Circle : System.IComparable<Circle>
{
    public int radius { get; private set; }
    public double Area()
    {
        return Math.PI * radius * radius;
    }
    public Circle(int radius)
    {
        this.radius = radius;
    }
    public int CompareTo(Circle c)
    {
        //you should not just return 1 or -1, you should return a value indicating their "distance"
        return (int)(this.Area() - c.Area());
    }
    public static bool operator >(Circle a, Circle b)
    {
        return a.CompareTo(b) > 0;
    }
}

Upvotes: 0

Tisho
Tisho

Reputation: 8482

public static bool operator < (Circle c1, Circle c2)
{
    return compare(c1, c2) < 0;
}

public static bool operator > (Circle c1, Circle c2)
{
    return compare(c1, c2) > 0;
}

public static bool operator == (Circle c1, Circle c2)
{
    return compare(c1, c2) == 0;
}

public static int compare(Circle c1, Circle c2)
{
    return c1.radius.CompareTo(c2.radius);
}

Upvotes: 1

Tigran
Tigran

Reputation: 62246

Another solution could be implementing IComparable for Circle type too. In that case, you can do , for example:

.....

if (c.Area().CompareTo(this.Area()) == 0)
     return 0;

.....

Upvotes: 0

Related Questions