gpt4 book ai didi

c# - 将通用 getter 表达式转换为对象 getter 表达式

转载 作者:太空宇宙 更新时间:2023-11-03 23:32:46 29 4
gpt4 key购买 nike

我有一个这样的表达式 setter/getter :

var expression = () => SomeInstance.Nr;

它被传递到一个方法中:

public void AddExpression<T>(Expression<Func<T>> func)

现在我想将该通用表达式转换为

Expression<Func<object>>

我不太确定我是否能做到这一点。我试过这样的事情:

var converted = Expression.Convert(func, typeof(object));
var objectExpression = Expression.Lambda<Func<object>>(Expression.Call(converted.Method), func.Parameters);

但是当我打电话的时候

var number = objectExpression.Compile()();

它不会返回属性值。

代码可以在这里测试: http://volatileread.com/utilitylibrary/snippetcompiler?id=25062

更新:似乎调用被第二次包装:

var converted = Expression.Convert(func, typeof(object));
var objectExpression = Expression.Lambda<Func<object>>(Expression.Call(converted.Method), func.Parameters);
var anotherDelegate = objectExpression.Compile().Invoke(); // would have expected the value here
var value = ((Delegate)anotherDelegate).DynamicInvoke(); // this now does return the value

最佳答案

不要使用 Expression.Call在委托(delegate)上——那只是用来调用方法的。相反,您想使用 Expression.Invoke ,它专门用于调用委托(delegate)。此外,执行表达式树的关键是包装 - 调用内部委托(delegate),转换结果,并将其包装在 lambda 中:

Expression<Func<int>> inputExpression = () => 42;

var newLambda =
Expression.Lambda<Func<object>>
(
Expression.Convert
(
Expression.Invoke(inputExpression),
typeof(object)
)
);

Console.WriteLine(newLambda.Compile()()); // Prints 42.

newLambdaExpression<Func<object>>并调用它给你 42 ,如您所料。

当然,这使得将其作为扩展方法变得相当容易(尽管您可能希望在需要时使用模板生成所有不同的 Func<...> 重载)。

请注意,只有当您使用的任何 LINQ 提供程序实际支持时,这才会起作用 Invoke - 在这种情况下,这不是问题,因为 lambda 编译器可以处理它,但是如果您需要使用类似这样的东西,例如EntityFramework,您需要采取稍微不同的方法 - 您需要展开内部 lambda,转换内部 lambda 的主体,然后将其再次包装在另一个 lambda 中。对于无参数表达式,这很容易:

Expression<Func<int>> inputExpression = () => 42;

var newLambda =
Expression.Lambda<Func<object>>
(
Expression.Convert(inputExpression.Body, typeof(object))
);

Console.WriteLine(newLambda.Compile()()); // Prints 42.

此外,为了完整起见,请注意,这仅在内部表达式确实是常量表达式而不是引号时有效 - 但如果您需要引用的嵌套表达式,您可能不会问这个问题 :D

关于c# - 将通用 getter 表达式转换为对象 getter 表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31557138/

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