Lambda表达式委托强类型与弱类型隐式转换方法

Tom*_*her 5 c# lambda

我有一个扩展方法,用于获取强类型Expression<Func<>>参数,但出于实现原因,我不得不将其更改为使用弱类型版本.这对表达式参数产生了奇怪的影响,因为它现在似乎是在对"转换"方法的显式调用中包装lambda表达式.

以前的参数看起来像:

m => m.Data
Run Code Online (Sandbox Code Playgroud)

现在它看起来如下:

m => Convert(m.Data)
Run Code Online (Sandbox Code Playgroud)

我已使用以下示例代码复制了该问题:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;

namespace ConsoleApplication
{
    static class Program
    {
        static void Main(string[] args)
        {
            Model model = new Model()
            {
                Data = 123
            };

            Test(m => m.Data, m => m.Data);

            Console.ReadLine();                
        }

        public static void Test<TProperty>(Expression<Func<Model, TProperty>> strongTyped, Expression<Func<Model, object>> weakTyped)
        {
            Console.WriteLine("Strong Typed: {0}", strongTyped);
            Console.WriteLine("Weak Typed: {0}", weakTyped);
        }
    }

    public class Model
    {
        public int Data
        {
            get;
            set;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

其输出如下:

Strong Typed: m => m.Data
Weak Typed: m => Convert(m.Data)
Run Code Online (Sandbox Code Playgroud)

我猜这与将值类型自动装入对象类型有关.任何人都可以证实这一点,或者有人知道发生了什么事吗?也有人知道Convert方法的声明在哪里吗?

在弱类型表达式上调用compile方法给出以下内容:

weakTyped.Compile().Method
{System.Object lambda_method(System.Runtime.CompilerServices.Closure, ConsoleApplication.Model)}
    [System.Reflection.Emit.DynamicMethod.RTDynamicMethod]: {System.Object lambda_method(System.Runtime.CompilerServices.Closure, ConsoleApplication.Model)}
    base {System.Reflection.MethodBase}: {System.Object lambda_method(System.Runtime.CompilerServices.Closure, ConsoleApplication.Model)}
    MemberType: Method
    ReturnParameter: null
    ReturnType: {Name = "Object" FullName = "System.Object"}
    ReturnTypeCustomAttributes: {System.Reflection.Emit.DynamicMethod.RTDynamicMethod.EmptyCAHolder}
Run Code Online (Sandbox Code Playgroud)

Rex*_*x M 3

Convert根本不是一种方法 - 它是一个UnaryExpression,实际上这就是你理论的原因 - 拳击/类型强制。有趣的是,当生成表达式树时,我们通常知道是隐式的东西实际上会显式地出现。

如果您自己构建表达式,则可以通过调用获得相同的效果Expression.Convert()

创建表示类型转换操作的 UnaryExpression。