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

标签 c# .net null icomparable

大多数人在编写实现 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 为空,则使用用户定义的比较,但如果相反,A 为空且 B 是对象,则使用某种 BCL 比较。

这是一个错误吗?

最佳答案

不,这不是错误。你的CompareTo实现 IComparable<Child> 的方法在您的 Child 上定义类(class)。换句话说,如果您必须调用一种类型的方法才能进行比较。

如果 Child 之一正在比较的项目为空,您如何调用 CompareTo在上面吗?

请注意,根据 IComparable 的定义:

By definition, any object compares greater than (or follows) a null reference (Nothing in Visual Basic), and two null references compare equal to each other.

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

解决方案是委托(delegate)其他一些类来执行比较。查看IComparer界面。

关于c# - 对 IComparable 对象进行排序,其中一些为 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6189750/

相关文章:

c# - 无法以编程方式覆盖 IIS 虚拟目录/应用程序中的文件(文件始终被锁定)

.net - 从套接字接收的流是否仅限于单个发送命令?

java - 为什么我的 Spring @Autowired 字段为空?

java - 在返回 double java的方法中返回null

c# - Elmah 日志错误页面自定义

c# - LINQ to XML - 将节点添加到 .csproj 文件

c# - 浏览器调用脚本

c# - 公共(public)密封类 SqlConnection : DbConnection, ICloneable

c# - 将带有 "&"的 XML 读入 C# XMLDocument 对象

android - 空对象引用上的 FragmentActivity.getSupportFragmentManager()'