Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 具有返回值的动态Linq表达式_C#_Expression Trees - Fatal编程技术网

C# 具有返回值的动态Linq表达式

C# 具有返回值的动态Linq表达式,c#,expression-trees,C#,Expression Trees,我需要创建一个动态linq表达式,我开始使用许多示例。我测试了一些工作,一些没有。在本例中,我希望创建一个如下所示的方法: public bool Check(int intvar) { if ( i > 2 ) return true; else return false; } 现在我写了以下内容: LabelTarget returnTarget = Expression.Label("label"); ParameterExpression para

我需要创建一个动态linq表达式,我开始使用许多示例。我测试了一些工作,一些没有。在本例中,我希望创建一个如下所示的方法:

public bool Check(int intvar)
{
   if ( i > 2 )
     return true;
   else
     return false;
}
现在我写了以下内容:

LabelTarget returnTarget = Expression.Label("label");
ParameterExpression para = Expression.Parameter(typeof(int), "intvalue");
Expression test = Expression.GreaterThan(para, Expression.Constant(5));
Expression iftrue = Expression.Return(returnTarget, Expression.Constant(true));
Expression iffalse = Expression.Return(returnTarget,                   Expression.Constant(false));
Expression.IfThenElse(test, iftrue, iffalse);

this.TheExpression = Expression.IfThenElse(test, iftrue, iffalse);
Expression.Lambda<Action<int>>(
this.TheExpression,
new ParameterExpression[] { para }
).Compile()(5);
labelTargetReturnTarget=Expression.Label(“Label”);
ParameterExpression para=表达式参数(typeof(int),“intvalue”);
表达式测试=表达式大于(第段,表达式常数(5));
表达式iftrue=Expression.Return(returnTarget,Expression.Constant(true));
表达式iffalse=Expression.Return(returnTarget,Expression.Constant(false));
表达式.IfThenElse(测试、iftrue、iffalse);
this.TheExpression=Expression.ifthenels(test,iftrue,iffalse);
Lambda(
这个表达,
新参数表达式[]{para}
).Compile()(5);
现在,它抛出InvalidOperationException:

无法跳转到标签“label”`


怎么了?我只需要返回true或false。

returnTarget
当前仅由if/then/else语句引用。标签不会放置在语句中的任何位置。所以它不知道跳到哪里。仅定义和引用标签,而不放置标签

尝试使用
Expression.Block
组合lambda和标签

Expression.Lambda<Action<int>>(
    Expression.Block(
        this.TheExpression,
        Expression.Label(returnTarget)
    ),
    new ParameterExpression[] { para }
    ).Compile()(5);
Expression.Lambda(
表达式块(
这个表达,
Expression.Label(返回目标)
),
新参数表达式[]{para}
).Compile()(5);
我还没有测试过,但这是你可以找到答案的大致方向

-更新-测试它,上面的lambda编译和运行就像现在一样


-update2-显然,您也想返回一个值,让我看看,至少,它应该是
Func
而不是
Action
,您需要更改一些内容:

  • 按照Rene的建议,将返回标签放在块表达式中函数的底部。这是您的
    return
    语句将跳转的地方

  • 将Lambda声明为type
    Func
    。因为您需要返回值,所以它需要是一个函数,而不是一个操作

  • returnTarget
    标签声明为type
    bool
    。由于块表达式的返回值是其最后一条语句的值,因此标签的类型必须正确

  • 为最终标签提供默认值(=如果通过正常控制流而不是
    return
    语句到达标签,则函数的返回值)

    labelTargetReturnTarget=Expression.Label(typeof(bool));
    ParameterExpression para=表达式参数(typeof(int),“intvalue”);
    表达式测试=表达式大于(第段,表达式常数(5));
    表达式iftrue=Expression.Return(returnTarget,Expression.Constant(true));
    表达式iffalse=Expression.Return(returnTarget,Expression.Constant(false));
    var ex=Expression.Block(
    表达式IfThenElse(测试、iftrue、iffalse),
    Expression.Label(returnTarget,Expression.Constant(false));
    var compiled=Expression.Lambda(
    前任,
    新参数表达式[]{para}
    ).Compile();
    Console.WriteLine(已编译(5));//打印“假”
    Console.WriteLine(已编译(6));//打印“真实”
    

如果您有这样的简单条件声明:

if(条件)
返回表达式1;
其他的
返回表达式2;
您可以将其转换为三元表达式:
条件?表达式1:expression2
。 然后可以创建表达式,而无需使用
Label
Return
Goto

表达条件;
表达1;
表达2;
/* ... */
表达式体=表达式.条件(
测试:条件,
如果真的是这样:表达1,
ifFalse:表达式2);

您能再告诉我们一些您想要实现的目标吗?例如,为什么需要动态创建此表达式。。。为什么需要使用标签以及if\else何时可以编写:public bool Check(int intvar){return i>2;}如果查看一些编译后的IL代码,您会发现它从未真正离开过…;)
LabelTarget returnTarget = Expression.Label(typeof(bool));
ParameterExpression para = Expression.Parameter(typeof(int), "intvalue");
Expression test = Expression.GreaterThan(para, Expression.Constant(5));
Expression iftrue = Expression.Return(returnTarget, Expression.Constant(true));
Expression iffalse = Expression.Return(returnTarget, Expression.Constant(false));

var ex = Expression.Block(
    Expression.IfThenElse(test, iftrue, iffalse),
    Expression.Label(returnTarget, Expression.Constant(false)));

var compiled = Expression.Lambda<Func<int, bool>>(
    ex,
    new ParameterExpression[] { para }
).Compile();

Console.WriteLine(compiled(5));     // prints "False"
Console.WriteLine(compiled(6));     // prints "True"