简体   繁体   中英

C# List sorting explanation needed

I have a problem which is already solved, but I don't know what really happens. Here is the simplified task: I have a list of records. The records consists of 2 fields, a key and a value . All keys are different. I want to sort them, so

  • I have a row with empty string as key , that should be in the first place.
  • The come the rows in which the value contains "Key not found" in alphabetical order by key
  • Then the rest of the rows in alphabetical order by key .

So I made this class:

private class RecordComparer : IComparer<GridRecord>
        {
            public int Compare(GridRecord x, GridRecord y)
            {
                if (x.Key == String.Empty)
                    return -1;
                else if (y.Key == String.Empty)
                    return 1;
                else if (x.Value.Contains("Key not found:") && !y.Value.Contains("Key not found:"))
                    return -1;
                else if (!x.Value.Contains("Key not found:") && y.Value.Contains("Key not found:"))
                    return 1;
                else return (x.Key.CompareTo(y.Key));
            }
        }

When I try to use it, I got Comparer (or the IComparable methods it relies upon) did not return zero when Array.Sort called x. CompareTo(x). x: '' x's type: 'GridRecord' The IComparer: Comparer (or the IComparable methods it relies upon) did not return zero when Array.Sort called x. CompareTo(x). x: '' x's type: 'GridRecord' The IComparer:
The error doesn't always appear, sometimes(usually when I use it first time in my program) it works fine. Second or third call crashes.

Inserting

if (x.Key == y.Key)
     return 0;

in the begginning of the Compare function above solved the problem, everything works fine. Why?

If you compare {Key=""} with anything, you are currently returning -1 . Even if you are comparing it with itself . When you compare something with itself (or something semantically equivalent to the same), you are supposed to return 0 . That is what the error is about.

It is wise to enforce total order in your custom comparer. One of the requirements for total order is reflexivity: for any x Compare(x, x) must be equal to zero. This property is required, for example, when comparer is used to sort an array with non-unique values.

Some libraries may do additional checks for custom comparers. There is no point to compare the element to itself, but on the other hand such check allow the runtime to find subtle errors (like the one you made). Probably thats why you've got your error message. Fixing such errors makes your code more stable. Usually the checks like this exist in debug builds only.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM