表达式树中未发生隐式转换 [英] Implicit Cast not happening in Expression Tree

查看:69
本文介绍了表达式树中未发生隐式转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了一种情况,我需要根据输入对不同属性的自定义类型列表进行排序.借助几篇文章,我得以提出使用LINQ的通用实现.在单元测试期间,其中一项测试失败,因为使用表达式树创建lamda表达式时发生了隐式转换.

I came across a scenario where I need to sort a list of custom type on different properties based on input. With the help of few articles, I was able to come up with generic implementation using LINQ.During unit testing, one of the test failed because implicit conversion was happening when lamda expression was created using Expression tree.

下面,我将示例代码理解为该问题(不确定为什么格式不正确,对此感到抱歉)

Below I have put the sample code to understand the issue (Not sure why formatting was not getting correct, 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();

    }
} 

在Main方法中,当我尝试将Func委托直接传递给Sort扩展方法时,它可以工作,但对于表达式树却失败.

In the Main method, when I try to pass a Func delegate directly to Sort extension method it works but it fails with Expression tree.

我找到了类似问题,但这是关于约束类型参数.两个问题都一样吗?有人可以帮我理解这个问题吗?

I found a similar issue, but that talks about constrained type parameters. Is both the issues same? Can somebody help me understand the issue.

推荐答案

您需要使用盒装版本(您当前 create boxingExpression ,但要使用最终查询在 propertyExpression 上):

You need to use the boxed version (you currently create boxingExpression, but base your final query instead on propertyExpression):

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

为什么它不是隐式的-这里只是 没有隐式转换; Expression != C#.装箱是一项重要的操作, Expression API需要在树中指定一个节点.

Re why this isn't implicit - there simply is no implicit casting here; Expression != C#. Boxing is a non-trivial operation, and the Expression API requires a specific node in the tree.

这篇关于表达式树中未发生隐式转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆