如何在运行时构建一个范围的 switch case 表达式?
How to build a ranged switch case expression at runtime?
我正在构建一个 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))
有没有更简洁的实现方式?有没有一种方法可以用根据范围评估切换值的表达式替换该常量表达式?性能也很重要,尤其是在范围很大的情况下。
您可以使用 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"
我正在构建一个 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))
有没有更简洁的实现方式?有没有一种方法可以用根据范围评估切换值的表达式替换该常量表达式?性能也很重要,尤其是在范围很大的情况下。
您可以使用 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"