views:

406

answers:

2

Hi,

I've been reading a book which is in C#. I'm a VB.NET developer (and a very junior one at that) and I'm having a lot of trouble with the following code that contains lots of things I've never seen before. I do have a basic knowledge of Lambda Expressions.

public List<T> SortByPropertyName(string propertyName, bool ascending)
{
    var param = Expression.Parameter(typeof(T), "N");

    var sortExpression = Expression.Lambda<Func<T, object>>
        (Expression.Convert(Expression.Property(param, propertyName),
        typeof(object)), param);

    if (ascending)
    {
        return this.AsQueryable<T>().OrderBy<T, object>(sortExpression).ToList<T>();
    }
    else
    {
        return this.AsQueryable<T>().OrderByDescending<T, object>(sortExpression).ToList<T>
    }
}

Could anybody illuminate me as to what this code is doing and what concepts are being used? I am also trying to convert this code into VB.NET with little luck so any help there would be appreciated as well.

+3  A: 

Overall, the code is sorting something (presumably a list?) by the specified property name in either ascending or descending order. There must already be a generic type T specified somewhere else in this class.

The code creates a new ParameterExpression by calling Expression.Parameter, then passes that parameter into the Expression.Lambda function, which creates a new lambda expression.

This expression is then used to sort the list by calling the OrderBy or OrderByDescending function (the choice depending on the ascending parameter) and returns the sorted list as a new List<T>.

I'm not in front of Visual Studio at the moment, but this should be a sufficiently close translation to VB for you.

Public Function SortByPropertyName(ByVal propertyName as String, ByVal ascending as Boolean) as List(Of T)
    Dim param = Expression.Parameter(GetType(T), "N")

    Dim sortExpression = Expression.Lambda(Of Func(Of T, Object))(Expression.Convert(Expression.Property(param, propertyName), GetType(Object)), param)

    If ascending Then
        return Me.AsQueryable(Of T).OrderBy(Of T, Object)(sortExpression).ToList()
    Else
        return Me.AsQueryable(Of T).OrderByDescending(Of T, Object)(sortExpression).ToList()
    End If
End Function
Adam Robinson
Thanks for the answer Adam. The main problem I'm having is with this line: var sortExpression = Expression.Lambda<Func<T, object>>(Expression.Convert(Expression.Property(param, propertyName), typeof(object)), param);What does <Func<T, object>> do? Is it saying that a generic function will be returned by Expression.Lambda()?
Andrew
Hmm...VS2008 doesn't seem to like:"return Me.AsQueryable(Of T).OrderBy(Of T, Object)(sortExpression).ToList()"I've tried: Return Queryable.AsQueryable(Of T)(Me).OrderBy(sortExpression).ToList()and it seems to like that, although I'm not sure if it's doing the same thing!
Andrew
A: 

This should work:

Return Me.AsQueryable.OrderBy(sortExpression).ToList

See also: http://www.codeproject.com/KB/recipes/Generic%5FSorting.aspx