可比较的实现
本文关键字:实现 可比较 | 更新日期: 2023-09-27 18:37:11
我写了以下代码
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 运算符">"不能应用于类型为"控制台应用程序 1.Circle"和"控制台应用程序 1.Circle"的操作数
我已经实现了这两种方法,但无法找出错误
您需要
重载>运算符才能执行您正在尝试的操作:
public static bool operator > (Circle c1, Circle c2)
{
return (c1.CompareTo(C2) > 0);
}
实现IComparable
或IComparable<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)
}
最后,>
和<
运算符实现需要考虑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);
}
实现 IComparable 本身不会为类创建>、>=、<、<= 运算符。如果您希望这些运算符可用于您的类,则必须实现它们:
public static bool operator > (Circle x, Circle y) {
return x.CompareTo(y) > 0;
}
// and so on for the other operators
如果决定创建这些运算符,则可能还需要重载 .等于方法和 == 运算符,以便 Circle 对象在实践中在比较操作下表现出值类型行为。
此外,由于面积与半径成正比,因此您可以比较半径(?拼写)而不是面积。
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);
}
另一种解决方案也可以为Circle
类型实现IComparable
。在这种情况下,您可以执行 ,例如:
.....
if (c.Area().CompareTo(this.Area()) == 0)
return 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;
}
}