0

我写了以下代码

 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;
    }
}

但是,错误 Error 1 Operator '>' 不能应用于“ConsoleApplication1.Circle”和“ConsoleApplication1.Circle”类型的操作数

我已经实现了这两种方法,但无法弄清楚错误

4

6 回答 6

6

您需要重载 > 运算符才能执行您正在尝试的操作:

  public static bool operator > (Circle c1, Circle c2)
  {
     return (c1.CompareTo(C2) > 0);
  }  
于 2012-06-15T07:24:50.140 回答
3

实现IComparableorIComparable<T>不会自动启用比较运算符的使用。您必须专门提供它们的实现。大多数其他答案(在此答案时)提供了不正确或不完整的运算符实现。

您需要首先修复您的CompareTo实现。第一个解决办法是确保您处理null案件。一个对象的比较总是大于null每个规范(请参阅 文档):

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;
}

的非泛型版本CompareTo还需要处理与对象的比较,null并以其他方式确保它确实与Circle对象进行比较:

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)
}

最后,>and<运算符的实现需要考虑其中一方或双方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);
}
于 2012-06-15T08:13:47.633 回答
1
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);
}
于 2012-06-15T07:31:36.520 回答
1

实现 IComparable 本身不会为该类创建 >、>=、<、<= 运算符。如果您希望这些运算符可用于您的类,则必须实现它们:

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

// and so on for the other operators

如果您决定创建这些运算符,您可能还希望重载 .Equals 方法和 == 运算符,以便您的 Circle 对象在实际比较操作下表现出值类型行为。

此外,由于面积与半径成正比,因此您最好比较半径(?拼写)而不是面积。

于 2012-06-15T07:40:15.700 回答
0

另一种解决方案也可以实现IComparable类型Circle。在这种情况下,您可以这样做,例如:

.....

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

.....
于 2012-06-15T07:27:57.323 回答
0

代码中的问题:
(1)您应该覆盖运算符>以将其与 2 个 Circle 对象一起使用。
(2) 在 compare 方法中,您应该返回一个值,指示与 Circle 对象之间的距离,而不仅仅是 1 或 -1 或 0 。
(3) 你应该调用一次Area()方法并保存它的值,然后在需要的时候使用这个值,而不是每次你需要的时候都使用这个方法。

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;
    }
}
于 2012-06-15T07:39:33.340 回答