Implicit merge does not occur in the expression tree

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}
                           };


        //This Works
        var sortUsingLamda = unOrderedStudents.Sort<Student>(stud => stud.Age, true);


        //Exception - Expression of type 'System.Int32' cannot be used for return type 'System.Object'
        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();

        //after adding Convert expression issue got fixed
        //return Expression.Lambda<Func<T, object>>(boxingExpression, 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.

, . ? - .

+5
3

( boxingExpression, propertyExpression):

return Expression.Lambda<Func<T, object>>(boxingExpression, param).Compile();

Re, - ; Expression!= #. - , API Expression node .

+5

GetSortFunc, Func < > , . - , , , .

int # , . , , Expression.Convert. , , #.

+2

Func<TSource, object> selector. , , TSource object. , :

     return Expression.Lambda<Func<T, object>>(boxingExpression, param).Compile();
+1
source

All Articles