是否有可能有一个出ParameterExpression?(Is it possible to ha

2019-09-22 06:03发布

我想定义与lambda表达式out参数。 是否有可能做到这一点?

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

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

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

我知道我可以使用输入类对象与布尔部件和值传回给调用者的方式,但我很好奇,如果我能以某种方式确定了参数。

谢谢

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

}

Answer 1:

您需要Type.MakeByRefType

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

请注意,您的代码示例还有另外一个问题:你的表情,身体是不正确的-这不是返回一个值时,它应该返回一个int满足委托类型的返回类型。

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

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

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

另外请注意,你不分配out的表达式中的参数。 Expression.Lambda是让你逃脱它,这是我没有想到的,但嘿,首创置业不必遵循相同的规则,C#!



文章来源: Is it possible to have an out ParameterExpression?