创建表达式以调用方法与参数出来 [英] Create expression to invoke method with out parameter

查看:134
本文介绍了创建表达式以调用方法与参数出来的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建调用的内部方法,内部方法有一个out参数的表达,这可能吗?



 公共类节目
{
静态无效的主要(字串[] args)
{
变种类型= ty​​peof运算(程序);
变种的MethodInfo = type.GetMethod(ValidateActiveControl,BindingFlags.Instance | BindingFlags.NonPublic可);

VAR P1 = Expression.Parameter(类型,计划);
VAR P2 = Expression.Parameter(typeof运算(布尔),validatedControlAllowsFocusChange);

VAR invokeExpression = Expression.Call(P1,MethodInfo的,P2);
变种FUNC =(Func键<程序,布尔,布尔>)Expression.Lambda(invokeExpression,P1,P2).Compile();

VAR validatedControlAllowsFocusChange = TRUE;
//我希望validatedControlAllowsFocusChange是执行...
Console.WriteLine后假(func.Invoke(新计划(),validatedControlAllowsFocusChange));
Console.WriteLine(validatedControlAllowsFocusChange);

}

内部布尔ValidateActiveControl(OUT BOOL validatedControlAllowsFocusChange)
{
validatedControlAllowsFocusChange = FALSE;

//此处是一些代码...

返回真;
}
}


解决方案

在除了吉姆的约MakeByRefType一点,你需要创建一个自定义的委托类型,因为函数功能不支持ref或out参数。全部放在一起:

 委托布尔ValidateDelegate(计划程序,OUT BOOL validatedControlAllowsFocusChange); 

静态无效的主要(字串[] args)
{
变种类型= ty​​peof运算(程序);
变种的MethodInfo = type.GetMethod(ValidateActiveControl,BindingFlags.Instance | BindingFlags.NonPublic可);

VAR P1 = Expression.Parameter(类型,计划);
VAR P2 = Expression.Parameter(typeof运算(布尔).MakeByRefType(),validatedControlAllowsFocusChange);

VAR invokeExpression = Expression.Call(P1,MethodInfo的,P2);
变种FUNC = Expression.Lambda&所述; ValidateDelegate>(invokeExpression,P1,P2).Compile();

VAR validatedControlAllowsFocusChange = TRUE;
//我希望validatedControlAllowsFocusChange是执行...
Console.WriteLine后假(func.Invoke(新计划(),出validatedControlAllowsFocusChange));
Console.WriteLine(validatedControlAllowsFocusChange);

}






编辑:这工作在.NET 4.0中,但不是在.NET 3.5。 3.5框架似乎并不支持lambda表达式树与out或ref参数。此代码:

 委托无效RefTest(OUT BOOL试验); 

静态无效的主要(字串[] args)
{
VAR P1 = Expression.Parameter(typeof运算(布尔).MakeByRefType(),测试);
VAR FUNC = Expression.Lambda< RefTest>(Expression.Constant(空),P1);
}



引发ArgumentExceptionlambda表达式不能包含引用参数通行证。我不认为你可以做你想做的,而不升级到.NET 4.0。


I am trying to create an expression that invokes an internal method, the internal method has an out parameter, is this possible?

public class Program
{
    static void Main(string[] args)
    {
        var type = typeof (Program);
        var methodInfo = type.GetMethod("ValidateActiveControl", BindingFlags.Instance | BindingFlags.NonPublic);

        var p1 = Expression.Parameter(type, "program");
        var p2 = Expression.Parameter(typeof (bool), "validatedControlAllowsFocusChange");

        var invokeExpression = Expression.Call(p1, methodInfo, p2);
        var func = (Func<Program,bool, bool>)Expression.Lambda(invokeExpression, p1, p2).Compile();

        var validatedControlAllowsFocusChange = true;
        // I would expect validatedControlAllowsFocusChange to be false after execution...
        Console.WriteLine(func.Invoke(new Program(), validatedControlAllowsFocusChange));
        Console.WriteLine(validatedControlAllowsFocusChange);

    }

    internal bool ValidateActiveControl(out bool validatedControlAllowsFocusChange)
    {
        validatedControlAllowsFocusChange = false;

        // Some code here...

        return true;
    }
}

解决方案

In addition to Jim's point about MakeByRefType, you will need to create a custom delegate type, since Func does not support ref or out parameters. Putting it all together:

delegate bool ValidateDelegate(Program program, out bool validatedControlAllowsFocusChange);

static void Main(string[] args)
{
    var type = typeof(Program);
    var methodInfo = type.GetMethod("ValidateActiveControl", BindingFlags.Instance | BindingFlags.NonPublic);

    var p1 = Expression.Parameter(type, "program");
    var p2 = Expression.Parameter(typeof(bool).MakeByRefType(), "validatedControlAllowsFocusChange");

    var invokeExpression = Expression.Call(p1, methodInfo, p2);
    var func = Expression.Lambda<ValidateDelegate>(invokeExpression, p1, p2).Compile();

    var validatedControlAllowsFocusChange = true;
    // I would expect validatedControlAllowsFocusChange to be false after execution...
    Console.WriteLine(func.Invoke(new Program(), out validatedControlAllowsFocusChange));
    Console.WriteLine(validatedControlAllowsFocusChange);

}


Edit: This works in .NET 4.0, but not in .NET 3.5. The 3.5 Framework doesn't appear to support lambda expression trees with out or ref parameters. This code:

delegate void RefTest(out bool test);

static void Main(string[] args)
{
    var p1 = Expression.Parameter(typeof(bool).MakeByRefType(), "test");
    var func = Expression.Lambda<RefTest>(Expression.Constant(null), p1);
}

throws an ArgumentException "A lambda expression cannot contain pass by reference parameters". I don't think you can do what you want without upgrading to .NET 4.0.

这篇关于创建表达式以调用方法与参数出来的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆