转换.NET函数功能< T>到.NET防爆pression< Func键< T>> [英] converting a .net Func<T> to a .net Expression<Func<T>>

查看:122
本文介绍了转换.NET函数功能< T>到.NET防爆pression< Func键< T>>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个lambda到防爆pression去很容易用一个方法调用...

Going from a lambda to an Expression is easy using a method call...

public void GimmeExpression(Expression<Func<T>> expression)
{
    ((MemberExpression)expression.Body).Member.Name; // "DoStuff"
}

public void SomewhereElse()
{
    GimmeExpression(() => thing.DoStuff());
}

不过,我想谈谈的Func键中的前pression,只有在极少数情况下...

But I would like to turn the Func in to an expression, only in rare cases...

public void ContainTheDanger(Func<T> dangerousCall)
{
    try 
    {
        dangerousCall();
    }
    catch (Exception e)
    {
        // This next line does not work...
        Expression<Func<T>> DangerousExpression = dangerousCall;
        var nameOfDanger = 
            ((MemberExpression)dangerousCall.Body).Member.Name;
        throw new DangerContainer(
            "Danger manifested while " + nameOfDanger, e);
    }
}

public void SomewhereElse()
{
    ContainTheDanger(() => thing.CrossTheStreams());
}

这是行不通的行给我的编译时错误无法隐式转换类型'System.Func&LT; T&GT;以System.Linq.Ex pressions.Ex pression&LT; System.Func&LT; T&GT;&GT; 。显式转换不解决问题。是否有工具来做到这一点,我可以俯瞰?

The line that does not work gives me the compile-time error Cannot implicitly convert type 'System.Func<T>' to 'System.Linq.Expressions.Expression<System.Func<T>>'. An explicit cast does not resolve the situation. Is there a facility to do this that I am overlooking?

推荐答案

哦,这是不容易的。 Func键&LT; T&GT; 重presents一个通用的代理,而不是前pression。如果有什么办法可以做到这一点(由于优化和编译器做其他的事情,有些数据可能被抛弃,所以它可能是不可能得到原来的前pression回),它会被拆解IL飞和推断EX pression(这绝不是简单的)。治疗拉姆达EX pressions数据(防爆pression&LT; Func键&LT; T&GT;&GT; )是一个神奇的编译器完成 (基本上是编译器生成其编译为IL在code的EX pression树代替)。

Ooh, it's not easy at all. Func<T> represents a generic delegate and not an expression. If there's any way you could do so (due to optimizations and other things done by the compiler, some data might be thrown away, so it might be impossible to get the original expression back), it'd be disassembling the IL on the fly and inferring the expression (which is by no means easy). Treating lambda expressions as data (Expression<Func<T>>) is a magic done by the compiler (basically the compiler builds an expression tree in code instead of compiling it to IL).

这就是为什么lambda表达式推到了极致(如Lisp)语言往往容易实施,因为除preters 。在这些语言中,code和数据在本质上是一样的东西(甚至在运行时间的),但我们的芯片无法理解code表示形式,所以我们要效仿这样的机器通过建立在它的上面是理解它(通过LISP喜欢语文的选择)跨preTER或牺牲功率(code将不再正好等于数据),在一定程度上(由做出的选择C#)。在C#中,编译器为处理code数据的假象,允许lambda表达式是PTED为 code Func键与其中除$ P $; T&GT; )和数据防爆pression&LT; Func键&LT; T&GT;&GT; )的编译时间

This is why languages that push lambdas to the extreme (like Lisp) are often easier to implement as interpreters. In those languages, code and data are essentially the same thing (even at run time), but our chip cannot understand that form of code, so we have to emulate such a machine by building an interpreter on top of it that understands it (the choice made by Lisp like languages) or sacrificing the power (code will no longer be exactly equal to data) to some extent (the choice made by C#). In C#, the compiler gives the illusion of treating code as data by allowing lambdas to be interpreted as code (Func<T>) and data (Expression<Func<T>>) at compile time.

这篇关于转换.NET函数功能&LT; T&GT;到.NET防爆pression&LT; Func键&LT; T&GT;&GT;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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