Skip to content

Month: June 2011

LINQ Order By Fun

I came across something at work the other day that I found interesting, and since I am never afraid to admit that I don’t know something, I thought I would post it.  Other than the fact that I used anonymous types to create the sample objects as opposed to writing classes, the code explains itself:

Public Sub TestLinqOrderBy()
        Dim f1 = New With {Key .Commodity = "Commod1", .Qty = 1000}
        Dim f2 = New With {Key .Commodity = "Commod2", .Qty = 2000}
        Dim f3 = New With {Key .Commodity = "Commod3", .Qty = 3000}

        Dim list1 = GetAnonymousList(f1)
        list1.Add(f1)
        list1.Add(f2)
        list1.Add(f3)

        'functionally these 2 calls are identical, since they are the same the rest of the example will use var
        Dim var = list1.OrderByDescending(Function(p) p.Qty) ' sort the list descending by quantity
        Dim var2 = From p In list1 Order By p.Qty Descending

        ' the list var now looks like this:
        'Commodity = "Commod3", Qty = 3000}
        'Commodity = "Commod2", Qty = 2000}
        'Commodity = "Commod1", Qty = 1000}

        'however, these will return you an IOrderedEnumerable (not an IEnumerable like most other simple linq queries), essentially a sorted list that will keep it sorted on the key
        'therefore, as statement like this may give you a list back you didnt expect because after the set has occurred, the IOrderedEnumerable will resort and keep itself sorted
        For i As Integer = 0 To 2
            var(i).Qty = New Random(i).Next(3000)
        Next

        ' since the above code changes the key of the list (Qty), it will set and reorder
        ' since you are looping through the list by index, you may not be changing the value in the list you thought you were when the loop began, 
        ' and the runtime will not tell you that you have modified the collection while looping

        ' the thing to note here is that if you specifiy an order by in your linq statement, that you are getting back a list that will always be sorted by the key, unless…
        ' if you want to sort a list with linq and then get it back without the live sorting, you can ToList your IOrderedEnumerable to return an IEnumerable
        Dim var3 = (list1.OrderByDescending(Function(p) p.Qty)).ToList  ' sort the list descending by quantity without live sorting
        'or
        Dim var4 = (From p In list1 Order By p.Qty Descending).ToList

        'YOU CAN PASTE THIS CODE INTO A NUNIT TEST CLASS AND STEP THROUGH IT IF YOU WANT TO SEE WHAT IS HAPPENING
    End Sub

    Private Function GetAnonymousList(Of T)(ByVal itemOfType As T) As List(Of T)
        Return New List(Of T)
    End Function
Leave a Comment