2012-06-15 3 views
0

я написал следующий кодIComparable Реализация

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'

я реализовал оба метод и не мог понять ошибку

ответ

1

Реализация IComparable сама по себе не создают>,> =, < <, = операторов для класса. Если вы хотите, чтобы эти операторы могли быть использованы с вами класса, вы должны реализовать их:

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

// and so on for the other operators 

Если вы решили создать эти операторы, вы также можете перегрузить метод .equals и оператор == так что ваш объект Circle будет на практике демонстрировать поведение типа значения в операциях сравнения.

Кроме того, поскольку Район прямо пропорционален радиусу, вы можете сравнить радиусы (? Орфографию) вместо областей.

+0

'IComparable' не говорит' 1', '0',' -1' - он говорит '<0', '0', '> 0'. В качестве общего примера это должно быть выражено как '> 0', а не' == 1' –

+0

Хорошая точка. Изменено. – user1429080

6

вы должны были бы перегружать> оператору делать то, что вы пытаетесь:

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

Педантизм: вы не * переопределяете * операторы; вы * перегружаете их –

+1

«IComparable предназначен только для проверки равенства» - это неверно. Но, как вы сказали, вам все равно нужно реализовать оператор <. – Henrik

+0

@MarcGravell, конечно, вы правы. Нужен кофеин ... – Dave

0

Другим решением может быть и IComparable для Circle. В этом случае, вы можете сделать, например:

..... 

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

..... 
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); 
} 
+0

thanx, который решает проблему – Akshita

0

Проблемы в коде:
(1) Вы должны переопределить оператор > использовать его с 2-х объектов Circle.
(2) В методе сравнения вы должны вернуть значение, указывающее расстояние между объектами 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; 
    } 
} 
3

Внедрение IComparable или IComparable<T> не позволяет автоматически использовать операторы сравнения. Вы должны конкретно обеспечить их реализацию. Большинство других ответов (во время этого ответа) предоставляют неверные или неполные реализации операторов.

Вам необходимо будет исправить свои CompareTo. Первое исправление заключается в том, чтобы убедиться, что вы обрабатываете случаи null.Объект всегда сравнивает больше чем null в соответствии со спецификациями (seedocs):

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

Наконец, реализация оператора > и < необходимо учитывать одну или обе стороны быть 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); 
} 
+1

Это лучший ответ, чем мой (который в настоящее время принят), поскольку предметом вопроса является «IComparable Implementation». +1 – user1429080

Смежные вопросы