ByRef parameters with expression trees in C #

If I wanted to create an expression tree that called a method with the out parameter and then returned the out value as the result .. how would I do it?

The following does not work (throws an exception at runtime), but perhaps best demonstrates what I'm trying to do:

 private delegate void MyDelegate(out int value); private static Func<int> Wrap(MyDelegate dele) { MethodInfo fn = dele.Method; ParameterExpression result = ParameterExpression.Variable(typeof(int)); BlockExpression block = BlockExpression.Block( typeof(int), // block result Expression.Call(fn, result), // hopefully result is coerced to a reference result); // return the variable return Expression.Lambda<Func<int>>(block).Compile(); } private static void TestFunction(out int value) { value = 1; } private static void Test() { Debug.Assert(Wrap(TestFunction)() == 1); } 

I know that this can be quite easily resolved in raw IL (or without compilation at all), but unfortunately this is part of a much larger process of constructing an expression ... so I really hope this is not a limitation, since full rewriting will be more than a little pain.

+7
source share
2 answers

This works for me:

  private static Func<int> Wrap(MyDelegate dele) { var fn = dele.Method; var result = ParameterExpression.Variable(typeof(int)); var block = BlockExpression.Block( typeof(int), new[] { result }, new Expression[] { Expression.Call(fn, result), result, }); return Expression.Lambda<Func<int>>(block).Compile(); } 
+7
source

Maybe it's just me, but I really don't see the point in this. To accomplish what you are trying to do, you do not need to write all this.

Example code in a console application:

  class Program { static void Main(string[] args) { var temp = Execute(DoSomething); Console.Write(temp); Console.Read(); } static int Execute(Func<int> methodToRun) { return methodToRun.Invoke(); } static int DoSomething() { return 1; } } 

As you can see, this gives you the same results in a more concise and clean way. I think that you were absent, so that Action , Action<> and Func<> are all syntactic sugar for the delegate , so there is no need to mix 2 syntaxes and no need to restore the whole expression as you do.

-4
source

All Articles