سؤال

I want to sort a list with the help of IComparable<T>.CompareTo for a type T called Path. I wrote

var shortest = new List<Path>();
//Fill shortest with elements != null
if (shortest.Contains(null))
      throw new System.Exception("Path is null");
shortest.Sort();
if (shortest.Contains(null))
      throw new System.Exception("Path is null");

To my surprise, the method

    int IComparable<Path>.CompareTo(Path other)
    {
        if (other == null)
            return -1;

        if (!other.valid)
            return 1;

        if (pfad.Count() > other.pfad.Count())
        {
            return -1;
        }
        else if (pfad.Count() < other.pfad.Count())
        {
            return 1;
        }
        else
        {
            if (length > other.length)
                return -1;
            else
                return 1;

        }

    }

from the class

 public class Path : IComparable<Path>

is called from Sort() with other==null. I am even more surprised that in the first code-block, the second exception is thrown, meaning that shortest contains a null value after the sort and not before.

هل كانت مفيدة؟

المحلول

Your CompareTo function is broken. It doesn't return 0 when an object is compared to itself and it always returns 1 when two objects with valid == false are compared. So there might be two objectsa and b with a.CompareTo(b) == 1 and b.CompareTo(a) == 1 and this might lead to Sort() behave strangely.

Also, as already noted in the other answer, it should return 1 if other == null. (shouldn't really matter when the list doesen't contain null)

نصائح أخرى

While I cannot explain why Sort needs to compare to null, the documentation of IComparable.CompareTo explicitly states:

By definition, any object compares greater than (or follows) null, and two null references compare equal to each other.

As such, whatever the reason is, the implementation of CompareTo has to follow this and the other rules to ensure compatibility with Sort() et al.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top