对IComparable对象进行排序,其中一些对象为null

Jep*_*eSN 6 .net c# null icomparable

大多数人在编写实现IComparable <T>的refence类型(类)时,使用null比任何实际对象都少的约定.但是如果你尝试使用相反的约定,会发生一些有趣的事情:

using System;
using System.Collections.Generic;

namespace SortingNulls
{
  internal class Child : IComparable<Child>
  {
    public int Age;
    public string Name;

    public int CompareTo(Child other)
    {
      if (other == null)
        return -1; // what's your problem?

      return this.Age.CompareTo(other.Age);
    }

    public override string ToString()
    {
      return string.Format("{0} ({1} years)", this.Name, this.Age);
    }
  }

  internal static class Program
  {
    private static void Main()
    {
      var listOfChilds = new List<Child>
      {
        null,
        null,
        null,
        null,
        new Child { Age = 5, Name = "Joe" },
        new Child { Age = 6, Name = "Sam" },
        new Child { Age = 3, Name = "Jude" },
        new Child { Age = 7, Name = "Mary" },
        null,
        null,
        null,
        null,
        new Child { Age = 7, Name = "Pete" },
        null,
        new Child { Age = 3, Name = "Bob" },
        new Child { Age = 4, Name = "Tim" },
        null,
        null,
      };

      listOfChilds.Sort();

      Console.WriteLine("Sorted list begins here");
      for (int i = 0; i < listOfChilds.Count; ++i)
        Console.WriteLine("{0,2}: {1}", i, listOfChilds[i]);
      Console.WriteLine("Sorted list ends here");
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

运行上面的代码时,您会看到空引用未按预期排序.显然,当比较A和B时,如果A是对象而B是null,则使用用户定义的比较,但如果相反A为空且B是对象,则使用某些BCL比较.

这是一个错误吗?

Col*_*inE 8

不,这不是一个错误.你的CompareTo方法,该方法实现IComparable<Child>是在您定义的Child类.换句话说,如果您必须在其中一个类型上调用方法以进行比较.

如果其中一个Child被比较的项目为null,您如何调用CompareTo它?

请注意,从IComparable的定义:

"根据定义,任何对象都比大于(或跟随)空引用(在Visual Basic中为Nothing),并且两个空引用相互比较相等."

这解释了您观察到的结果.

解决方案是委托其他一些类来执行比较.请参阅IComparer接口.