有没有可能有一个ParameterExpression?

问题描述:

我想用out参数定义Lambda表达式。可以做到吗?有没有可能有一个ParameterExpression?

下面是我尝试过的C#.Net 4.0控制台应用程序中的代码片段。

正如你可以Procedure25看到我可以使用lambda表达式定义但有一个输出参数,一个代表,当我想用​​LINQ表达式做同样的,在步骤24中的代码失败:

System.ArgumentException了未处理消息= ParameterExpression类型的“System.Boolean” 不能用于 类型的代表参数“System.Boolean &”源= System.Core程序

我知道我可以使用一个输入类obj等一个bool成员,然后将值返回给调用者,但我很好奇,如果我能以某种方式定义出参数。

感谢

static void Main(string[] args) 
{ 
    Procedure25(); 
    Procedure24(); 
    Console.WriteLine("Done!"); 
    Console.ReadKey(); 
} 

private delegate int Evaluate(string value, out bool usesVars); 

private static void Procedure24() 
{ 

    // This fails to compile: 
    //Expression<Evaluate> x = (string val, out bool usesSimVals) => 
    //{ 
    // usesSimVals = true; 
    // Console.WriteLine(val); 
    // return 1; 
    //}; 


    ParameterExpression valueParameter = Expression.Parameter(typeof (string)); 
    MethodCallExpression methodCall = Expression.Call(typeof(Console).GetMethod("WriteLine", new Type[] { typeof(object) }), valueParameter); 

    bool usesVars; 
    ParameterExpression usesVarsParameter = Expression.Parameter(typeof (bool), "out usesVars"); 


    Expression.Lambda<Evaluate>(methodCall, valueParameter, usesVarsParameter).Compile()("test", out usesVars); 
    Console.WriteLine(usesVars); 

} 

private static void Procedure25() 
{ 
    Evaluate x = (string value, out bool vars) => { vars = true; 
    Console.WriteLine(value); 
                return 1; 
    }; 

    bool usesVars; 
    x("test", out usesVars); 
} 

编辑:

安仁,真棒,谢谢。所以关键的是在参数类型上调用MakeByRefType。

对于这里的记录是作品基于阿尼的建议的代码片段:

private static void Procedure24() 
{ 
    ParameterExpression valueParameter = Expression.Parameter(typeof (string)); 
    MethodCallExpression methodCall = Expression.Call(typeof(Console).GetMethod("WriteLine", new Type[] { typeof(object) }), valueParameter); 

    bool usesVars; 
    ParameterExpression usesVarsParameter = Expression.Parameter(typeof (bool).MakeByRefType(), "out usesVars"); 

    Expression block = Expression.Block(methodCall, Expression.Assign(usesVarsParameter, Expression.Constant(true)), Expression.Constant(1)); 
    int result = Expression.Lambda<Evaluate>(block, valueParameter, usesVarsParameter).Compile()("test", out usesVars); 
    Console.WriteLine("Result={0}, usesVars={1}", result, usesVars); 

} 

您需要Type.MakeByRefType

var usesVarsParameter = Expression.Parameter(typeof(bool).MakeByRefType(), "usesVars"); 

请注意,您的代码示例还有另外一个问题:你的expression- body不正确 - 当它返回int以满足委托类型的返回类型时,它不会返回值。

这里您可以修复的方式(如您的拉姆达为例):

var body = Expression.Block(methodCall, Expression.Constant(1)); 

Expression.Lambda<Evaluate>(body, valueParameter, usesVarsParameter) 
      .Compile()("test", out usesVars); 

另外请注意,您不分配表达式中的out参数。 Expression.Lambda正在让你摆脱它,我没有想到,但嘿,BCL不必遵循与C#相同的规则!