Sorting in .NET

I found some very interesting behavior in the .NET sort method today that I thought I would share in case it catches anyone else off guard.

To set up the scenario, I had two objects that had the same value for the property that was being compared. These objects were already in the order I wanted them to be in; although, in the context of the other objects in the list, they needed to be sorted correctly. The result was the two objects with the same value were now in the opposite order. I’ve provided a little sample code that demonstrates the problem.

  internal static class Program
  {
      private static void Main()
      {
          var list = new List {
                                  new MyClass("Alpha", DateTime.Today),
                                  new MyClass("Beta", DateTime.Today),
                                  new MyClass("Charlie", DateTime.Today)
                              };
          list.Sort();
          list.ForEach(d => Console.WriteLine(d));
          // Expected output:
          // Alpha      11/28/2011 12:00:00 AM
          // Beta       11/28/2011 12:00:00 AM
          // Charlie    11/28/2011 12:00:00 AM
          // Actual output:
          // Charlie    11/28/2011 12:00:00 AM
          // Beta       11/28/2011 12:00:00 AM
          // Alpha      11/28/2011 12:00:00 AM
      }
  }

  internal struct MyClass : IComparable
  {
      public string MyName;

      public DateTime MyDate;

      public MyClass(string myName, DateTime myDate)
      {
          this.MyName = myName;
          this.MyDate = myDate;
      }

      public int CompareTo(MyClass other)
      {
          return DateTime.Compare(this.MyDate, other.MyDate);
      }

      public override string ToString()
      {
          return string.Format("{0,-10} {1,-30}", this.MyName, this.MyDate);
      }
  }

In order to fix my sorting behavior, I had to add another field to make sure that the sort was maintained with values that were the same.

  public int CompareTo(MyClass other)
  {
      var result = DateTime.Compare(this.MyDate, other.MyDate);
      return result == 0 ? this.MyName.CompareTo(other.MyName) : result;
  }

That solved my problem, hopefully it helps if someone else runs into this issue.

Josh Minnie

Christian, family man, web developer. I love spending time with my family and my job is also my hobby. Owner of Nissi Solutions.