来自 msdn 示例的 c# 中的 IComparer语言 - - MSDN 部分的误导性



我有以下方法:

public static void OrderByDescendingEx1()
{
    List<decimal> decimals = new List<decimal> { 6.2m, 8.3m, 0.5m, 1.3m, 6.3m, 9.7m };
    IEnumerable<decimal> query =  
        decimals.OrderByDescending(num => num, new SpecialComparer());
    foreach (decimal num in query)
    {
        Console.WriteLine(num);
    }
}

这是IComparer的实现

public class SpecialComparer : IComparer<decimal>
{
    /// <summary>
    /// Compare two decimal numbers by their fractional parts.
    /// </summary>
    /// <param name="d1">The first decimal to compare.</param>
    /// <param name="d2">The second decimal to compare.</param>
    /// <returns>1 if the first decimal's fractional part 
    /// is greater than the second decimal's fractional part,
    /// -1 if the first decimal's fractional
    /// part is less than the second decimal's fractional part,
    /// or the result of calling Decimal.Compare()
    /// if the fractional parts are equal.</returns>
    public int Compare(decimal d1, decimal d2)
    {
        decimal fractional1, fractional2;
        // Get the fractional part of the first number.
        try
        {
            fractional1 = decimal.Remainder(d1, decimal.Floor(d1));
        }
        catch (DivideByZeroException)
        {
            fractional1 = d1;
        }
        // Get the fractional part of the second number.
        try
        {
            fractional2 = decimal.Remainder(d2, decimal.Floor(d2));
        }
        catch (DivideByZeroException)
        {
            fractional2 = d2;
        }
        if (fractional1 == fractional2)
            return Decimal.Compare(d1, d2);
        else if (fractional1 > fractional2)
            return 1;
        else
            return -1;
    }
}

输出为

 /*
         This code produces the following output:
         9.7
         0.5
         8.3
         6.3
         1.3
         6.2
        */

所以我的问题与数学和 c# 都相关。输出不按降序排序。那为什么这段代码是正确的呢?

更新

在解释中,Microsoft写道:"按降序对序列的元素进行排序"。更好,更好,如果他们说to sort the elements' fractions of a sequence in descending order.

他们使用的英语并不复杂,很简单:to sort the elements of a sequence in descending order并不意味着对序列元素的分数进行排序

数据按

降序排列 - 由比较器定义。

比较器按小数点的小数部分排序,其余部分仅用于决胜局。所以1.2先于1.30.3,但在12.1之后。这就是为什么你甚至不得不编写自己的比较器 - 你想要的东西不是通常的比较。

代码是正确的,不是因为它按降序对集合进行排序,而是因为它旨在显示创建自定义 Comparer 的含义。

在这种情况下,微软通过展示这一点来"好玩",一方面,您实现了按分数进行比较并按分数正确排序:

//Let's call this View 1
.7
.5
.3
.3
.3
.2

但另一方面,除了平局情况外,也没有正确地按实际值降序:

//Let's call this View 2
9.7
0.5
8.3
6.3
1.3
6.2

对我来说,这样说有双重目的:

  1. 这是一个正确的降序比较器(通过显示它根据分数正确排序) - 视图 1
  2. 它是一个定制的比较器(通过显示它根据分数部分进行排序) - 视图 2

我个人认为这是一个深思熟虑的(聪明的)例子。如果没有像Microsoft那样创建自定义比较器,该示例可能会更加模棱两可,因为人们可能会错过上述两点中的任何一点。即:

  1. 这是一个正确的比较器,但似乎没有自定义:

     5.6, 4.5, 3.7, 2.9
    
  2. 它不是比较器(如果数据结果未显示模式):

    +, ?, &, 54, u
    

最新更新