C# Sort()和CompareTo()方法的内部工作

C# Sort()和CompareTo()方法的内部工作,c#,sorting,compareto,icomparable,C#,Sorting,Compareto,Icomparable,我一直在试图弄清楚CompareTo()方法在内部是如何工作的,但失败了。我搜索了这个网站并阅读了一些帖子,我想我已经看到了MSDN中关于这个主题的所有内容,但我似乎不明白。MSDN示例: public int CompareTo(object obj) { if (obj == null) { return 1; } Temperature otherTemperature = obj as Temperature; if (other

我一直在试图弄清楚
CompareTo()
方法在内部是如何工作的,但失败了。我搜索了这个网站并阅读了一些帖子,我想我已经看到了MSDN中关于这个主题的所有内容,但我似乎不明白。MSDN示例:

public int CompareTo(object obj)
{
    if (obj == null)
    {
        return 1;
    }

    Temperature otherTemperature = obj as Temperature;
    if (otherTemperature != null)
    {
        return this.temperatureC.CompareTo(otherTemperature.temperatureC);
    }
    else
    {
        throw new ArgumentException("the object is not a temperature");
    }
}
这是
CompareTo()
方法实现的MSDN示例。我了解这一点,我了解
IComparable
接口是如何工作的,如果我理解正确,在使用
ArrayList.Sort()方法时会调用它

我不明白的是:程序何时将
CompareTo(objectobj)
方法的参数传递给?或者换句话说,
Sort()
方法是如何工作的?我的意思是,这段代码将一个温度实例与另一个温度实例进行比较,但程序何时或如何获取第二个温度实例以进行比较?我希望我的问题有意义

我试着在屏幕上打印
CompareTo()
过程,这样也许我可以对输出进行反向工程,但我更困惑了自己

编辑
也许我可以一步一步地解释清楚。假设我在
ArrayList
中有3个温度对象:34、45、21。当我调用
ArrayList.Sort()
时,
CompareTo()
方法是否被称为像
34.CompareTo(45)
?然后是
45。与(21)
相比?返回的整数在第一次比较中为1,在第二次比较中为-1?如果我只定义了
CompareTo()
方法,仅当obj(参数)为null时才返回1,那么这些整数是如何返回的?我没有定义任何返回-1或0的内容。就好像我正在实现一个已经实现的方法。定义一个
CompareTo()
方法,当它已经被定义为返回-1、0和1时。

当您想将
a
b
进行比较时,您可以说:

int result=a.CompareTo(b);
即,第一个比较操作数是this
,第二个是传递给函数的参数


然后,在对数组进行排序时,无论使用何种算法,都必须将元素比较在一起,将它们作为
this
obj
发送到
object.CompareTo
(或此函数的可行重载)。

简言之,sort将使用ArrayList中的两个元素,并为第一个元素调用CompareTo,并将第二个元素作为参数传递,如下所示:

element1.CompareTo(element2)

如果element1小于element2,则CompareTo返回负值;如果相等,则返回0;否则返回正值。Sort使用这个返回值,嗯,进行一些排序。然后对接下来的两个元素重复这个过程,再进行一些排序,依此类推,直到对ArrayList进行排序。搜索“排序算法”以获取有关此过程的更多信息。

排序方法独立于
比较方法。我不确定使用了什么排序算法,但我猜它类似于快速排序(obv不是冒泡排序)。如果你对这些算法感兴趣,维基百科会详细记录它们

CompareTo
方法只是比较相同类型对象的一种方法。它是为许多常见的.NET类型定义的,并且可以被覆盖以在自定义对象(您创建的对象)之间进行比较。基本上,从类型为A的对象调用它,并将第二个类型为A的对象传递给它,返回值指示两者是否相等或一个大于另一个


最好将
与进行比较,将其视为一个实用函数。它的存在使您可以使用公共.NET数据结构提供的排序方法进行自定义比较。如果没有类似的东西,您必须自己编写排序算法,以便比较您创建的类型。它的目的只是使排序方法可重用/可扩展。

有不同的排序算法。但是,无论在什么情况下,算法都必须决定哪个元素更大,这是在调用
CompareTo

a.CompareTo(b) < 0;

我想你会在很多伪码或整数排序算法的例子中找到
a
符号
CompareTo
IComparable的方法是一种面向对象的实现或表示法。

让我们从基本思想开始

比较的目的是什么? 42比1337是多少。是42。。。大于、小于或等于1337

此问题及其答案由
IComparable
IComparable
界面中的
CompareTo
方法建模。对于
A.与(B)
相比,该方法可以返回:

  • A大于B:一个大于0的整数值
  • A小于B:一个小于0的整数值
  • A等于B:一个等于0的整数值
当然,
IComparable
不限于整数。您可以实现
IComparable
来比较您认为可以比较的任何两个对象。例如,字符串:

什么是“犰狳”到“十二生肖”:是“犰狳”。。。大于、小于或等于“黄道带”

答案取决于您对大于、小于和等于的定义。对于字符串,通常的顺序是字典中出现得较晚的单词大于出现得较早的单词

CompareTo如何帮助排序? 好了,现在你知道如何比较任意两个物体了。这对许多算法很有用,但主要是排序和排序算法。以一个非常简单的排序算法为例:愚蠢的排序。这个想法是:

查看数组中的两个相邻元素A和B。
当A B时:交换A和B,并返回到上一对。
当我们到达终点时,我们就结束了

你看,要进行排序,必须有一种方法来确定两个元素中哪一个更大。那就是
a < b
public static void StupidSort<T>(T[] array)
            where T : IComparable<T>
{
    int index = 0;
    while (index < array.Length)
    {
        if (index == 0 ||
            array[index - 1].CompareTo(array[index]) <= 0)
        {
            index++;
        }
        else
        {
            Swap(array, index - 1, index);
            index--;
        }
    }
}