Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does ascending keyword exist purely for clarity when used with orderby?

If i do a query, ordering elements as below, i get ascending order.

var i = from a in new int[] { 1, 2, 3, 4, 5 }
        orderby a
        select a;

If i add the ascending keyword i get the same results.

var i = from a in new int[] { 1, 2, 3, 4, 5 }
        orderby a ascending
        select a;

I recognise that adding the ascending keyword in the second example could increase readability as it removes the need to know the default order of orderby.

Is there any other reason for the ascending keyword to exist?

I'm also, interested in knowing why this (breaking change?) was implimented just for use in one particular case.

Edit: See comments below, @Joey points out, it's not a breaking change as it's a contextual keyword.

like image 659
George Duckett Avatar asked Jun 08 '11 10:06

George Duckett


1 Answers

Yes it is redundant. There is no circumstance when it does anything different since the order is implicitly ascending.

I guess it provides completeness, but it does indeed seem a shame to introduce a keyword into the language that is so... impotent.

On the other side, though:

  • it mimics SQL, which is broadly related in terms of semantics
  • it avoids the "how do I?" questions
  • it does no harm, and nobody is forcing you to use it
  • it (arguably) makes things clearer if you have a descending, b ascending, c descending, d ascending etc

Example (see comments) that order by a, order by b is actually very different to order by a, b:

public static void Main()
{
    var data = new[] { new { X = 1, Y = 1 }, new { X = 1, Y = 2 },
                       new { X = 2, Y = 1 }, new { X = 2, Y = 2 } };

    foreach (var pair in from p in data orderby p.X, p.Y select p)
    {
        Console.WriteLine("{0},{1}", pair.X, pair.Y);
    }
    Console.WriteLine();
    foreach (var pair in from p in data orderby p.X orderby p.Y select p)
    {
        Console.WriteLine("{0},{1}", pair.X, pair.Y);
    }
}

prints:

1,1
1,2
2,1
2,2

1,1
2,1
1,2
2,2

note the middle two are reversed. This is because of the difference between:

data.OrderBy(p => p.X).ThenBy(p => p.Y)

in the first loop, and

data.OrderBy(p => p.X).OrderBy(p => p.Y)

in the second.

Because LINQ attempts to guarantee a stable sort (i.e. when there are matches, the data is retained in the original order), an OrderBy().OrderBy() does the first sort (on X), and then resorts the data, only looking at the original (sorted by X) order when the Ys match. Or in other words: it flips them left-to-right.

like image 174
Marc Gravell Avatar answered Oct 27 '22 01:10

Marc Gravell