【发布时间】:2011-08-29 20:20:54
【问题描述】:
此代码适用于 .NET4:
class Program
{
static void Main( string[] args )
{
var fooExpr = Expression.Parameter( typeof( Foo ), "f" );
var parmExpr = Expression.Parameter( typeof( int ).MakeByRefType(), "i" );
var method = typeof( Foo ).GetMethod( "Method1" );
var invokeExpr = Expression.Call( fooExpr, method, parmExpr );
var delegateType = MakeDelegateType( typeof( void ), new[] { typeof( Foo ), typeof( int ).MakeByRefType() } );
var lambdaExpr = Expression.Lambda( delegateType, invokeExpr, fooExpr, parmExpr );
dynamic func = lambdaExpr.Compile();
int x = 4;
func( new Foo(), ref x );
Console.WriteLine( x );
}
private static Type MakeDelegateType( Type returnType, params Type[] parmTypes )
{
return Expression.GetDelegateType( parmTypes.Concat( new[] { returnType } ).ToArray() );
}
}
class Foo
{
public void Method1( ref int x )
{
x = 8;
}
}
此代码不会(在动态调用站点出现运行时错误):
class Program
{
static void Main( string[] args )
{
var fooExpr = Expression.Parameter( typeof( Foo ), "f" );
var parmExpr = Expression.Parameter( typeof( int ).MakeByRefType(), "i" );
var method = typeof( Foo ).GetMethod( "Method1" );
var invokeExpr = Expression.Call( fooExpr, method, parmExpr );
var delegateType = MakeDelegateType( typeof( void ), new[] { typeof( Foo ), typeof( int ).MakeByRefType() } );
var lambdaExpr = Expression.Lambda( delegateType, invokeExpr, fooExpr, parmExpr );
dynamic func = lambdaExpr.Compile();
int x = 4;
func( new Foo(), out x );
Console.WriteLine( x );
}
private static Type MakeDelegateType( Type returnType, params Type[] parmTypes )
{
return Expression.GetDelegateType( parmTypes.Concat( new[] { returnType } ).ToArray() );
}
}
class Foo
{
public void Method1( out int x )
{
x = 8;
}
}
怎么会?唯一的区别是使用 ref 与 out 参数。
【问题讨论】:
-
错误是:“委托
有一些无效参数”...没有更多细节,没有内部异常。 -
出于好奇,如果您在呼叫站点使用
ref而不是out会发生什么?另外,如果你用正确的outetc 签名声明一个委托类型,并尝试一个静态类型的编译 lambda,会发生什么? -
哇,奇怪...如果我在调用站点使用'ref'(并在方法声明中保留'out'),那就可以了。一个错误?编辑 - 再三考虑,不是错误。奇怪的是,没有明确的方法可以在动态构造的委托类型上创建“out”参数。谢谢马克。
标签: .net c#-4.0 expression-trees