10

The new ValueTuple types in C# 7 implement IComparable, but the only documentation I have been able to find on their implementation of this simply states that CompareTo's return value indicates relative position "in the sort order". It does not state what the "sort order" referred to actually is.

By examining the source, I can find that the order is what I would expect - it delegates to comparing the first field by its default Comparer, then using the other fields one at a time, in order, to break ties. I would prefer not to depend on this without a guarantee that it's not considered an implementation detail that could change without violating specification, however.

Is this behavior actually documented anywhere?

Douglas
  • 5,017
  • 1
  • 14
  • 28

1 Answers1

8

According to the source code, CompareTo calls the Compare methods of the default comparers

    public int CompareTo(ValueTuple<T1, T2, T3> other)
    {
        int c = Comparer<T1>.Default.Compare(Item1, other.Item1);
        if (c != 0) return c;

        c = Comparer<T2>.Default.Compare(Item2, other.Item2);
        if (c != 0) return c;

        return Comparer<T3>.Default.Compare(Item3, other.Item3);
    }

but you can explicitly provide a customer comparer

int IStructuralComparable.CompareTo(object other, IComparer comparer)
devio
  • 36,858
  • 7
  • 80
  • 143
  • 1
    Source code is not specification or documentation, unless it's in a documentation comment. – Douglas Oct 18 '17 at 06:20
  • 2
    @Douglas in this case it is, especially as tuples evolve from one C# version to the next. The C# 6 specification was just finished, C# 7 specs are a work in progress and we are in C# 7.2 already – Panagiotis Kanavos Oct 18 '17 at 09:24
  • @Douglas, completely disagree. The code is the primary source of documentation; it's the only documentation that precisely describes what the resultant app or library does. And [the tests](https://github.com/dotnet/corefx/blob/master/src/System.ValueTuple/tests/ValueTupleTests.cs) are the specification of what it should do. Everything else is supplementary and risks being out of sync and thus wrong. – David Arno Oct 18 '17 at 10:09
  • 5
    @DavidArno A specification is a document that I could point to when filing a bug report to support my statement that what the source code does is wrong. The code cannot be such a document because it is inherently unable to disagree with itself in such a way. The tests are not such a document because they do not cover every case or state the general principles that could support a bug report about a case they missed. – Douglas Oct 18 '17 at 15:57
  • 2
    @Douglas that would be true 5 years ago, only for *closed* source projects. The language though is in constant development *as an open source project*. The C# 6 spec is actually a *draft* - it's not finished yet. You don't need the *spec* to file a bug - people report language issues all the time in the [chsarplang](https://github.com/dotnet/csharplang) repo - there are 696 open issues at this time. The *design* itself is open to discussion, the discussions and decisions posted on the repo. – Panagiotis Kanavos Oct 19 '17 at 12:04
  • @Douglas, I'd suggest you check out the number of tests in my link. The chances of anyone, ever, writing a traditional spec that goes into more detail than those tests capture is vanishingly small. Those tests are the most detailed specification that will ever be produced. They are the specification. As Panagiotis says, if you need to file a bug, point to the test when reporting the code is wrong. – David Arno Oct 20 '17 at 07:56