我想用out
参数定义Lambda表达式。有可能吗?
以下是我尝试的C#.Net 4.0控制台应用程序的代码片段。
正如您在Procedure25中看到的,我可以使用lambda表达式来定义具有输出参数的委托,但是,当我想使用linq表达式执行相同操作时,过程24中的代码将失败:
System.ArgumentException未处理Message = ParameterExpression 类型' System.Boolean'不能用于类型的委托参数 '&System.Boolean放大器;'源= 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<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);
}
编辑:
<...> 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<Evaluate>(block, valueParameter, usesVarsParameter).Compile()("test", out usesVars);
Console.WriteLine("Result={0}, usesVars={1}", result, usesVars);
}
答案 0 :(得分:8)
var usesVarsParameter = Expression.Parameter(typeof(bool).MakeByRefType(), "usesVars");
请注意,您的代码示例还有一个问题:表达式主体不正确 - 当它应返回int
以满足委托类型的返回类型时,它不会返回值。
这是一种可以修复它的方法(就像你的lambda示例):
var body = Expression.Block(methodCall, Expression.Constant(1));
Expression.Lambda<Evaluate>(body, valueParameter, usesVarsParameter)
.Compile()("test", out usesVars);
另请注意,您未在表达式中指定out
参数。 Expression.Lambda
让你逃脱它,我没想到,但是,嘿,BCL不必遵循与C#相同的规则!