如何在运行时构建有范围的开关案例表达式?

时间:2019-01-16 10:14:02

标签: c# switch-statement expression expression-trees

我正在构建一个Switch表达式,以在运行时匹配整数范围。 目前,我可以使用Expression.SwitchCase编译并运行以下命令:

switch(value)
{
    case 1:
    case 2:
        Console.WriteLine("1 or 2");
        break;
    case 3:
    case 4:
    case 5:
        Console.WriteLine("3, 4 or 5");
        break;
}

我的问题是-我必须为我要匹配的范围内的每个常量创建一个SwitchCase:

Expression.SwitchCase(body, Expression.Constant(1))

Expression.SwitchCase(body, Expression.Constant(2))

是否有更简洁的方法来实现这一目标?有没有一种方法可以将我的常量表达式替换为根据范围评估开关值的表达式?性能也很有趣,尤其是在范围较大的情况下。

1 个答案:

答案 0 :(得分:1)

您可以使用其他Expression.SwitchCase重载来简化代码

只需创建一个具有测试值的数组并将其转换为ConstantExpression。试试这个例子:

var writeLine = typeof(Console).GetMethod("WriteLine", new[] {typeof(string)});

// body of first block
var action1 = Expression.Call(writeLine, Expression.Constant("1 or 2"));
// body of second block
var action2 = Expression.Call(writeLine, Expression.Constant("3, 4 or 5"));

var value = Expression.Parameter(typeof(int), "value");
var body = Expression.Switch(value,
    Expression.SwitchCase(
      action1,
      new[] {1, 2}.Select(i => Expression.Constant(i))),
    Expression.SwitchCase(
      action2, 
      new[] {3, 4, 5}.Select(i => Expression.Constant(i)))
);

var lambda = Expression.Lambda<Action<int>>(body, value);
var method = lambda.Compile();

method(1); // print "1 or 2"
method(4); // print "3, 4 or 5"