Get link to parameter inside lambda passed as Func

Given the following set of classes:

public class MyClass
{
    public int MyInt { get; set; }
}    

public class ObjectProcessor
{
    public int ProcessObject(MyClass myClass)
    {
        return myClass.MyInt ++;
    } 
}

public class Runner
{
    public void Run()
    {
        var classToPass = new MyClass();

        FuncExecutor.ExecuteAction<MyClass>(x => x.ProcessObject(classToPass));
    }
}

public static class FuncExecutor
{
    public static void ExecuteAction<T>(Expression<Func<ObjectProcessor, int>> expression)
    {
        // var func = expression.Compile(); ... does having an Expression help?

        // How can I get a reference to 'classToPass' at this point?

        // The 'classToPass' Type is known to be 'T', in this case 'MyClass'.
    }
}

From the method ExecuteAction, how can I get a link to the instance classToPassthat was passed in ProcessObject?

EDIT: The comments emphasized the difficulty of trying to parse expression trees, which can vary greatly in their composition.

However, in this particular case, there are two facts that significantly reduced this option:

  • ProcessObject will take only one parameter.
  • The type of parameter is known in advance.

Changed code to express this.

+3
source share
2 answers

To answer very specifically:

public class Runner
{
    public void Run()
    {
        var classToPass = new MyClass();
        classToPass.MyInt = 42;

        FuncExecutor.ExecuteAction(x => x.ProcessObject(classToPass));
    }
}

public class FuncExecutor
{
    public static void ExecuteAction(Expression<Func<ObjectProcessor, int>> expression)
    {
        var lambdaExpression = (LambdaExpression)expression;
        var methodCallExpression = (MethodCallExpression)lambdaExpression.Body;

        var memberExpression = (MemberExpression)methodCallExpression.Arguments[0];
        var constantExpression = (ConstantExpression)memberExpression.Expression;
        var fieldInfo = (FieldInfo)memberExpression.Member;

        var myClassReference = (MyClass) fieldInfo.GetValue(constantExpression.Value);

        Console.WriteLine(myClassReference.MyInt); // prints "42"
    }
}

, ExecuteAction, (classToPass). . , () MyClass, . MemberExpression .

, Value. MemberInfo ( ).

.

, lambda, : http://thewalkingdev.blogspot.fr/2012/04/c-lambda-expressions-and-closures.html

+1

- ExecuteAction . , :

public interface IObjectProcessor<T> {
    public int ProcessObject(T instance);
}

public class MyClassProcessor : IObjectProcessor<MyClass> {
    public int ProcessObject(MyClass myClass) {
        return myClass.MyInt ++;
    }
}

public class Runner {
    public void Run() {
        var classToPass = new MyClass();
        var processor = new MyClassProcessor();

        FuncExecutor.ExecuteAction<MyClass>(processor, classToPass);
    }
}

public class FuncExecutor {
    public static void ExecuteAction<T>(IObjectProcessor<T> processor, T obj) {
        int result = processor.ProcessObject(obj);
    }
}

, " ", Func as. :

public class MyClassProcessor
    public static int ProcessObject(MyClass myClass) {
        return myClass.MyInt ++;
    }
}

public class Runner {
    public void Run() {
        var classToPass = new MyClass();

        FuncExecutor.ExecuteAction<MyClass>(MyClassProcessor.ProcessObject, classToPass);
    }
}

public class FuncExecutor {
    public static void ExecuteAction<T>(Func<T, int> process, T obj) {
        int result = process(obj);
    }
}
+1

All Articles