ByRef parameters with Expression trees in C#
If I wanted to create an expression tree that called a method with an out
parameter and then returned the out
value as a result.. how would I go about it?
The following does not work (throws a runtime exception), 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 this can be fairly easily solved in raw IL (or indeed without runtime compilation at all), but unfortunately this is part of a much larger expression building process... so I'm really hoping this isn't a limitation, as a complete rewrite would be more than a bit of a pain.
这适用于我:
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();
}
Maybe it's just me, but I don't really see the point of the whole thing. To accomplish what you're trying to do, you don't really need to write all that stuff.
Sample code in a console app:
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 see it gets you the same results in a more concise and clean way. What I think you were missing out is that Action
, Action<>
and Func<>
are all sintactic sugar for delegate
so no need to mix the 2 syntaxes and no need to reconstruct the whole expression like you are doing.
上一篇: 模板代码上的编译器堆栈溢出
下一篇: 在C#中使用表达式树的ByRef参数