C# 如何从lambda表达式获取引用实例的实例

C# 如何从lambda表达式获取引用实例的实例,c#,delegates,lambda,C#,Delegates,Lambda,我有这个lambda表达式表达式命令执行 然后我用一个方法传递其中一个类的实例: _commandExecuter.ProcessCommand (() => aClass.Method()) 如何在ProcessCommand方法中获取aClass的实例 我想执行这个类的一些附加方法或获取一些属性值 这可能吗 编辑: 现在,我编写了一个简单的静态助手方法来获取实例: private static object GetReferredProviderInstance(Expression

我有这个lambda表达式
表达式命令执行

然后我用一个方法传递其中一个类的实例:

_commandExecuter.ProcessCommand (() => aClass.Method())
如何在
ProcessCommand
方法中获取
aClass
的实例

我想执行这个类的一些附加方法或获取一些属性值

这可能吗

编辑: 现在,我编写了一个简单的静态助手方法来获取实例:

private static object GetReferredProviderInstance(Expression body)
{
    var methodCallExpression = body as MethodCallExpression;
    if (methodCallExpression != null)
    {
        var constantExpression = methodCallExpression.Object as ConstantExpression;
        if (constantExpression != null) return constantExpression.Value;
    }
    return null;
}
方法调用如下所示

Expression body = commandToExecute.Body; // this is the method parameter Expression<Func<bool>> commandToExecute
var referredProviderInstance = GetReferredProviderInstance(body);
但这里出现了一个新问题。我只获取提供程序的引用实例所在的windows窗体实例

如何获得lambda表达式的真实对象
aClass
)呢?

不可能“开箱即用”,您可以通过反射来破解某些东西,但这是不可取的,它将非常落后。
编辑:根据罗纳德的说法,这实际上是可能的,但仍然非常落后。这样隐藏的副作用使代码难以阅读和维护


相反,您的ProcessCommand应该使用整个
aClass
对象,或者更可取的是使用
.Method()
ProcessCommand
所需的附加方法和属性的
IMyCommand
接口。然后,
aClass.GetType()
类型应该实现
IMyCommand

,这实际上是可能的,但这取决于传递给此方法的内容。假设您有这样一个场景,将所处类的实例方法传递给
ProcessCommand

public class TestClass
{
    public void TestMethod()
    {
        ProcessCommand(() => MethodToCall());
    }
    public bool MethodToCall() { return true; }
    void ProcessCommand(Expression<Func<bool>> expression) { ... }
}
更复杂的情况如下:

public class CallingClass
{
    public void TestMethod()
    {
        var calledClass = new CalledClass();
        ProcessCommand(() => calledClass.MethodToCall());
    }
    void ProcessCommand(Expression<Func<bool>> expression) { ... }
}
public class CalledClass
{
    public bool MethodToCall() { return true; }
}

稍微复杂一点,因为编译器必须生成一个匿名内部类。

如果它回答了您的问题,请您将其标记为答案好吗?结果比我最初想象的要复杂一点。我用一个太简单的例子进行了测试。我将更新我的答案,以显示它到底是如何可能的。
void ProcessCommand(Expression<Func<bool>> expression)
{
    var lambda = (LambdaExpression) expression;
    var methodCall = (MethodCallExpression) lambda.Body;
    var constant = (ConstantExpression) methodCall.Object;
    var myObject = constant.Value;
}
public class CallingClass
{
    public void TestMethod()
    {
        var calledClass = new CalledClass();
        ProcessCommand(() => calledClass.MethodToCall());
    }
    void ProcessCommand(Expression<Func<bool>> expression) { ... }
}
public class CalledClass
{
    public bool MethodToCall() { return true; }
}
public void ProcessCommand(Expression<Func<bool>> expression)
{
    // The expression is a lambda expression with a method call body.
    var lambda = (LambdaExpression) expression;
    var methodCall = (MethodCallExpression) lambda.Body;
    // The method is called on a member of some instance.
    var member = (MemberExpression) methodCall.Object;
    // The member expression contains an instance of the anonymous class that
    // defines the member...
    var constant = (ConstantExpression) member.Expression;
    var anonymousClassInstance = constant.Value;
    // ...and the member itself.
    var calledClassField = (FieldInfo) member.Member;
    // With an instance of the anonymous class and the field, we can get its value.
    var calledClass =
        (CalledClass) calledClassField.GetValue(anonymousClassInstance);
}