Сортировка IComparable объектов, некоторые из которых имеют значение NULL

Большинство людей при написании типа (класса) ссылки, который реализует IComparable , используют соглашение, согласно которому 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");
    }
  }
}

При запуске приведенного выше кода вы увидите, что пустые ссылки не отсортированы должным образом. Очевидно, при сравнении A с B, если A является объектом, а B имеет значение NULL, используется определяемое пользователем сравнение, но если, наоборот, A имеет значение NULL и B является объектом, вместо этого используется некоторое сравнение BCL.

Это ошибка?

6
задан JeppeSN 31 May 2011 в 15:14
поделиться