C# 从MethodCallExpression访问调用对象

C# 从MethodCallExpression访问调用对象,c#,C#,我试图学习表达式树,我创建了一个方法,它采用 Expression<Func<bool>> 是空的。很明显我做错了什么!如何访问方法正在操作的实例?方法调用的目标是MyClass的实例,但委托本身不是方法调用。它将在执行时执行方法调用 如果你看func.Target,你会发现它是一个 现在,您可以对此进行测试,对其进行强制转换,然后获取本地或全局数据,但不确定要获取目标。但是,我怀疑,如果只更改为使用Func或任何类型的错误代码,并在第一次执行委托时返回错误代码,会更

我试图学习表达式树,我创建了一个方法,它采用

Expression<Func<bool>> 

是空的。很明显我做错了什么!如何访问方法正在操作的实例?

方法调用的目标是MyClass的实例,但委托本身不是方法调用。它将在执行时执行方法调用

如果你看func.Target,你会发现它是一个

现在,您可以对此进行测试,对其进行强制转换,然后获取本地或全局数据,但不确定要获取目标。但是,我怀疑,如果只更改为使用Func或任何类型的错误代码,并在第一次执行委托时返回错误代码,会更干净。这样你就不需要表达式树了

编辑:根据您的意见,我建议:

public static void TryCommand(Expression<Func<MyClass,bool>> command,
                              MyClass c)
{
    // Code as before to find the method name etc.

    Func<MyClass, bool> compiled = command.Compile();

    if (!compiled(c))
    {
        Console.WriteLine(methodCallExpression.Method.Name
            + "() failed with error code " + c.GetError());
    }
}

方法调用的目标是MyClass的实例,但委托本身不是方法调用。它将在执行时执行方法调用

如果你看func.Target,你会发现它是一个

现在,您可以对此进行测试,对其进行强制转换,然后获取本地或全局数据,但不确定要获取目标。但是,我怀疑,如果只更改为使用Func或任何类型的错误代码,并在第一次执行委托时返回错误代码,会更干净。这样你就不需要表达式树了

编辑:根据您的意见,我建议:

public static void TryCommand(Expression<Func<MyClass,bool>> command,
                              MyClass c)
{
    // Code as before to find the method name etc.

    Func<MyClass, bool> compiled = command.Compile();

    if (!compiled(c))
    {
        Console.WriteLine(methodCallExpression.Method.Name
            + "() failed with error code " + c.GetError());
    }
}

目标为null,因为该方法是静态的。在反射中调用。。在静态MethodInfo上,将忽略目标。这可能是一种扩展方法,在这种情况下,第一个参数是推断的目标


由于大多数LINQ是基于扩展方法的,您将经常看到这一点与反射有关。

目标是空的,因为该方法是静态的。在反射中调用。。在静态MethodInfo上,将忽略目标。这可能是一种扩展方法,在这种情况下,第一个参数是推断的目标


由于大多数LINQ都是基于扩展方法的,因此在反射中经常会看到这一点。

Akash,一旦有了MethodCallExpression,恢复方法调用方就很简单了。 您必须恢复MemberExpression并构建一个表达式树来计算它

请参阅下面的代码:


MethodCallExpression methodCallExpression = (MethodCallExpression)expression.Body;
MemberExpression memberExpression = (MemberExpression)methodCallExpression.Object;

Expression<Func<Object>> getCallerExpression = Expression<Func<Object>>.Lambda<Func<Object>>(memberExpression);
Func<Object> getCaller = getCallerExpression.Compile();
MyClass caller = (MyClass)getCaller();
希望这有帮助


Ricardo Lacerda Castelo Branco

Akash,一旦有了MethodCallExpression,恢复方法调用方就很简单了。 您必须恢复MemberExpression并构建一个表达式树来计算它

请参阅下面的代码:


MethodCallExpression methodCallExpression = (MethodCallExpression)expression.Body;
MemberExpression memberExpression = (MemberExpression)methodCallExpression.Object;

Expression<Func<Object>> getCallerExpression = Expression<Func<Object>>.Lambda<Func<Object>>(memberExpression);
Func<Object> getCaller = getCallerExpression.Compile();
MyClass caller = (MyClass)getCaller();
希望这有帮助


里卡多·拉塞达·卡斯特罗·布兰科

Jon,我正在与第三方MyClass合作抱歉,我的名字不好!,所以我不能把它改成Func[int]。我会研究你的第一个建议。我同意它看起来不干净,但我主要是在学习什么是可能的。谢谢你的建议!如何调用TryCommand?你能控制这一切吗?您可以编写一个包装器方法,它接受一个Func和一个MyClass,然后调用委托并检查错误代码(如果需要)。我当前使用的是TryCommand=>MyClass.SomeMethod。。。。。MyClass有许多返回bool和设置错误代码的方法,所以我认为TryCommand处理错误处理会很好。我可以使用TryCommandFunc[bool],我的类,但想看看我能把表达式推到什么程度!Jon,我在和第三方MyClass合作抱歉,我的名字不好!,所以我不能把它改成Func[int]。我会研究你的第一个建议。我同意它看起来不干净,但我主要是在学习什么是可能的。谢谢你的建议!如何调用TryCommand?你能控制这一切吗?您可以编写一个包装器方法,它接受一个Func和一个MyClass,然后调用委托并检查错误代码(如果需要)。我当前使用的是TryCommand=>MyClass.SomeMethod。。。。。MyClass有许多返回bool和设置错误代码的方法,所以我认为TryCommand处理错误处理会很好。我可以使用TryCommandFunc[bool],我的类,但想看看我能把表达式推到什么程度!

MethodCallExpression methodCallExpression = (MethodCallExpression)expression.Body;
MemberExpression memberExpression = (MemberExpression)methodCallExpression.Object;

Expression<Func<Object>> getCallerExpression = Expression<Func<Object>>.Lambda<Func<Object>>(memberExpression);
Func<Object> getCaller = getCallerExpression.Compile();
MyClass caller = (MyClass)getCaller();