gpt4 book ai didi

c# - 将 .net Func 转换为 .net Expression>

转载 作者:IT王子 更新时间:2023-10-29 03:34:37 26 4
gpt4 key购买 nike

使用方法调用很容易从 lambda 转换为表达式...

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

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

但我想将 Func 转换为表达式,只是在极少数情况下......

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

不起作用的行给我编译时错误 Cannot implicitly convert type 'System.Func<T>' to 'System.Linq.Expressions.Expression<System.Func<T>>' .显式转换不能解决这种情况。是否有我忽略的执行此操作的工具?

最佳答案

哦,一点也不简单。 Func<T>代表一个通用的 delegate而不是一个表达。如果有任何方法可以这样做(由于优化和编译器所做的其他事情,一些数据可能会被丢弃,因此可能无法恢复原始表达式),它会即时反汇编 IL并推断表达式(这绝非易事)。将 lambda 表达式视为数据 ( Expression<Func<T>> ) 是 编译器 的魔法(基本上,编译器在代码中构建表达式树,而不是将其编译为 IL)。

相关事实

这就是为什么将 lambda 推向极致的语言(如 Lisp)通常更容易实现为解释器。在这些语言中,代码和数据本质上是同一件事(即使在运行时),但我们的芯片无法理解这种形式的代码,因此我们必须通过在其上构建解释器来模拟这样的机器理解它的人(Lisp 做出的选择,如语言)或在某种程度上牺牲能力(代码将不再完全等于数据)(C# 做出的选择)。在 C# 中,编译器允许将 lambda 解释为代码 ( Func<T> ) 和 数据 ( Expression<Func<T>> ) >编译时间。

关于c# - 将 .net Func<T> 转换为 .net Expression<Func<T>>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/767733/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com