是否可以使用ParameterExpression?

我想用out参数定义Lambda表达式。 有可能吗?

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

正如您在Procedure25中看到的,我可以使用lambda表达式来定义具有输出参数的委托,但是,当我想使用linq表达式执行相同操作时,过程24中的代码将失败:

System.ArgumentException未处理Message = ParameterExpression类型’System.Boolean’不能用于’System.Boolean&’Source = System.Core类型的委托参数

我知道我可以使用带有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 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(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); } 

编辑:

Ani,太棒了,谢谢。 所以关键是在参数类型上调用MakeByRefType。

这里的记录是一个代码片段,根据Ani的建议工作:

 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(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"); 

请注意,您的代码示例还有一个问题:表达式主体不正确 – 当它应该返回一个int以满足委托类型的返回类型时,它不返回值。

这是一种你可以解决的方法(就像你的lambda例子):

 var body = Expression.Block(methodCall, Expression.Constant(1)); Expression.Lambda(body, valueParameter, usesVarsParameter) .Compile()("test", out usesVars); 

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