.net - 表达式树 : invoking a method with out or ref arguments

标签 .net c#-4.0 expression-trees

此代码适用于 .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 参数。

最佳答案

A 引用 参数将由 CLR 管理一个经典变量,如果这个变量是一个值,它将只是 Box(封装到一个对象中以通过引用传递元素)。

允许有多个输出,并且在编译过程中会产生更大的影响。

表达式在运行时编译,但在编译时检查“out”有效性。

通过有效性,我的意思是编译器确保方法 将分配 值到 范围。

关于.net - 表达式树 : invoking a method with out or ref arguments,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6075460/

相关文章:

c# - 将字段从一个 Windows 窗体传递到另一个 Windows 窗体时,哪种技术更好?

c# - 设置为最大化的 WinForm 在循环中出现得太早

.net - 为什么 Thread.Sleep(0) 可以解决我的问题,以及如何避免它?

c# - 使用类型约束实现泛型类时出错

c#-4.0 - C# : AsParallel - does order matter?

c# - MemberExpression : InvalidOperationExpression variable 'x' referenced from scope '' , 但未定义

c# - 组合 Where 语句的表达式

c# - ThreadStart.BeginInvoke 在 Compact 框架上抛出 NotSupportedException

.net - 回调方法 C#

algorithm - 根据霍纳方案,将多项式的解析树转换为其评估的解析树