gpt4 book ai didi

c# - Expression.Lambda() 的参数问题

转载 作者:行者123 更新时间:2023-12-01 20:24:09 24 4
gpt4 key购买 nike

更新:这确实有效,我很愚蠢:(

我有以下扩展方法

public static string ExtMethod(this object self, object myparameter);

在运行时,可以通过多种方式调用它,我认为这些都是可能的:

Expression<Func<T, string>> expr = x => x.property.ExtMethod(5);
Expression<Func<T, string>> expr = x => x.property.ExtMethod(new object());
Expression<Func<T, string>> expr = x => x.property.ExtMethod(someMethod());
Expression<Func<T, string>> expr = x => x.property.ExtMethod(x.someMethod());
Expression<Func<T, string>> expr = x => x.property.ExtMethod(x.OtherProperty);

我需要做的是评估“myparameter”,给定“expr”和“T

由于 xmyparameter 中使用的两种情况,我认为我需要创建以下形式的委托(delegate):

Expression<Func<T, object>> expr = x => [myparameter expression here]

我认为这会起作用:

var extMethodExpr = expr.Body as MethodCallExpression;
var myparameterExpr = extMethodExpr.Arguments[1];

var myparam = Expression.Lambda(myparameterExpr, expr.Parameters).Compile().Invoke(someT)

但是对于不涉及x的表达式, 我得到 TargetParameterCountException :(

在这些情况下,如果我这样做:

var myparam = Expression.Lambda(myparameterExpr).Compile().Invoke(someT)

效果很好。

如何解决这个问题?

谢谢

最佳答案

好的;追根究底;行中:

var myparam = Expression.Lambda(myparameterExpr).Compile().Invoke(someT);

如果您没有尝试传入 someT,这适用于参数中不涉及 x 的表达式;对于那些这样做的人,您需要告诉 lambda 包含该参数(与原始 lambda 相同的参数) - 只需通过:

var myparam = Expression.Lambda(myparameterExpr,
outerLambda.Parameters[0]).Compile().Invoke(someT);

这是一些计算内部参数的工作代码(给定参数类型的实例);请注意,即使它涉及x,我也会使用该参数 - 否则,它会对实例做什么?

using System;
using System.Linq.Expressions;
using System.Reflection;
class Foo {
public string Bar {get;set;}
public int someMethod() { return 4; }
public int OtherProperty { get { return 3; } }
}
static class Program
{
static int someMethod() { return 3; }
static void Main()
{
Foo foo = new Foo();
Test<Foo>(x => x.Bar.ExtMethod(5), foo);
Test<Foo>(x => x.Bar.ExtMethod(new object()), foo);
Test<Foo>(x => x.Bar.ExtMethod(someMethod()), foo);
Test<Foo>(x => x.Bar.ExtMethod(x.someMethod()), foo);
Test<Foo>(x => x.Bar.ExtMethod(x.OtherProperty), foo);
}
static void Test<T>(Expression<Func<T, string>> expr, T instance)
{
if (expr.Body.NodeType != ExpressionType.Call)
{
throw new InvalidOperationException("Call expected");
}
var call = ((MethodCallExpression)expr.Body);
if (call.Method != typeof(Program).GetMethod(
"ExtMethod", BindingFlags.Static | BindingFlags.NonPublic))
{
throw new InvalidOperationException("ExtMethod expected");
}
// we know that ExtMethod has 2 args; pick myParameter (the 2nd);
// then build an expression over arg, re-using our outer param
var newLambda = Expression.Lambda<Func<T, object>>(
call.Arguments[1], expr.Parameters[0]);

// evaluate it and show the argument value
object value = newLambda.Compile()(instance);
Console.WriteLine(value);
}
static string ExtMethod(this object self, object myParameter) {
return self.ToString();
}
}

关于c# - Expression.Lambda() 的参数问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/903558/

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