代码之家  ›  专栏  ›  技术社区  ›  Rohan West

创建表达式以调用带out参数的方法

  •  9
  • Rohan West  · 技术社区  · 14 年前

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

    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;
        }
    }
    
    2 回复  |  直到 14 年前
        1
  •  12
  •   Quartermeister    14 年前

    Func 不支持ref或out参数。综合起来:

    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);
    
    }
    

    编辑:这在.NET4.0中有效,但在.NET3.5中无效。3.5框架似乎不支持带有out或ref参数的lambda表达式树。此代码:

    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);
    }
    

    抛出ArgumentException“lambda表达式不能包含按引用传递的参数”。我不认为不升级到.NET4.0你就可以随心所欲。

        2
  •  1
  •   Joseph Yaduvanshi    14 年前

    根据 this blog post

    typeof(bool).MakeByRefType();