I came across a scenario where I need to sort a list of a custom type by various input-based properties. Through several articles, I was able to come up with a common implementation using LINQ. During unit testing, one of the tests failed because an implicit conversion occurred when the lamda expression was created using the expression tree.
Below I put the example code to understand the problem (I donβt know why the formatting did not work correctly, sorry for that)
static class ExtensionMethods
{
public static IEnumerable<TSource> Sort<TSource>(this IEnumerable<TSource> unSortedList, Func<TSource, object> selector, bool isAscending)
{
return isAscending ? unSortedList.OrderBy(selector) : unSortedList.OrderByDescending(selector);
}
}
class Program
{
class Student
{
public string Name { get; set; }
public int Age { get; set; }
}
static void Main(string[] args)
{
var unOrderedStudents = new List<Student>
{
new Student{ Name="A", Age=20},
new Student{Name = "B", Age=19}
};
var sortUsingLamda = unOrderedStudents.Sort<Student>(stud => stud.Age, true);
var sortUsingExpressionTree = unOrderedStudents.Sort<Student>( GetSortFunc<Student>("Age"), true);
Console.WriteLine("Press any key to continue");
Console.ReadLine();
}
private static Func<T, object> GetSortFunc<T>(string sortColumn)
{
var param = Expression.Parameter(typeof(T), "entity");
var propertyExpression = Expression.Property(param, sortColumn);
var boxingExpression = Expression.Convert(propertyExpression, typeof(object));
return Expression.Lambda<Func<T, object>>(propertyExpression, param).Compile();
}
}
In the main method, when I try to pass the Func delegate directly to the sort sort method, it works, but it does not work with the expression tree.
, . ? - .