为什么在实现CompareTo时必须重载运算符? [英] Why do I have to overload operators when implementing CompareTo?

查看:91
本文介绍了为什么在实现CompareTo时必须重载运算符?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个实现IComparable的类型.

Let's say I have a type that implements IComparable.

我认为可以合理地期望运算符==!=><>=<=将通过调用CompareTo自动正常工作",但我有如果要使用它们,请覆盖它们.

I would have thought it's reasonable to expect that the operators ==, !=, >, <, >= and <= would "just work" automatically by calling CompareTo but instead I have to override them all if I want to use them.

从语言设计的角度来看,这样做有充分的理由吗?在某些情况下,A>B的行为不同于Compare(A,B)>0确实有用吗?

From the language design perspective is there a good reason it was done this way? Are there any cases when you it's genuinely useful for A>B to behave differently to Compare(A,B)>0?

推荐答案

整个情况令人烦恼. C#有太多表达平等和不平等的方法:

The whole situation is vexing. C# has too many ways to express equality and inequality:

  • ==!=>< > =< =运算符(在逻辑上是静态方法)
  • Equals静态方法(称为虚拟方法),Equals虚拟方法,ReferenceEquals方法
  • IComparable和IEquatable接口

它们的语义都有细微的不同,除了静态Equals之外,没有一个自动使用另一个,并且没有一个实际上具有我想要的行为.静态方法是根据两个操作数的编译时类型分派的.虚拟方法/接口方法是根据操作数的 one 的运行时类型调度的,从而使操作不对称.一侧的类型比另一侧的类型重要.

They all have subtly different semantics and with the exception of static Equals, none automatically uses the other, and none actually has the behavior that I want. Static methods are dispatched based on the compile-time type of both operands; the virtual methods / interface methods are dispatched based on the run-time type of one of the operands, which makes the operation asymmetric; the type of one side matters more than the type of the other.

我无法想象有人会认为我们所处的局势很好;在没有任何限制的情况下,这不会发生任何变化.但是托管语言设计人员确实有一些约束条件:CLR不会在接口协定或双虚拟分派中实现静态方法,也无法将操作符约束置于通用类型参数上.因此,已经出现了多种解决方案来解决平等/不平等问题.

I can't imagine that anyone thinks that the situation we're in is great; given no constraints, this is not what would have evolved. But managed language designers do have constraints: the CLR does not implement static methods in interface contracts or double-virtual dispatch, or the ability to put an operator constraint on a generic type parameter. And therefore multiple solutions have evolved to solve the equality/inequality problem.

我认为CLR和C#设计人员可以追溯到过去,并告诉他们过去自己应该在CLR v1中拥有哪些功能,所以接口中的某种形式的静态方法会排在首位.如果接口中有静态方法,那么我们可以定义:

I think that were the CLR and C# designers to go back in time and tell their past selves what features ought to be in v1 of the CLR, some form of static methods in interfaces would be high on the list. If there were static methods in interface then we can define:

interface IComparable<in T, in U> 
{
    static bool operator <(T t, U u);
    static bool operator >(T t, U u);
    ... etc

然后,如果您有:

static void Sort<T>(T[] array) where T : IComparable<T, T>

然后可以使用<==等运算符来比较元素.

You could then use the < and == and so on operators to compare elements.

这篇关于为什么在实现CompareTo时必须重载运算符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆