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

ただし、エラー エラー 1 演算子 '>' はタイプ '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

IComparableorを実装IComparable<T>しても、比較演算子の使用が自動的に有効になるわけではありません。それらの実装を具体的に提供する必要があります。(この回答の時点で)他の回答のほとんどは、演算子の不正確または不完全な実装を提供します。

実装を修正することから始める必要がありますCompareTo。最初の修正は、ケースを確実に処理することですnull。オブジェクトは常に仕様よりも大きいものを比較しますnull( 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;
}

の非ジェネリック バージョンも、オブジェクトとのCompareTo比較を処理する必要があります。nullCircle

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 メソッドでは、 1 または -1 または 0 だけでなく、 Circle オブジェクト間の距離を示す値を返す必要があります。 (3) Area() メソッドを 1 回呼び出してその値を保存し、必要なときに毎回このメソッドすべてを使用するのではなく、必要に応じてこの値を使用する必要があります。>

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 に答える