Expression.Switch()在案例实现方面苦苦挣扎

时间:2015-11-20 11:06:58

标签: c# expression

我试图实现Expression.Switch()在我的表达式中创建一个switch语句。我正在努力解决一些问题。

我创建了一个引发异常的小例子。交换机使用字符串来切换案例,在这种情况下,它将分配一个变量。

以下是一些会引发异常的代码:

// an int variable
var var1 = Expression.Parameter(typeof(int));
// a string variable
var var2 = Expression.Parameter(typeof(string));

var cases = new[] 
{ 
    // the first case 'SwitchCaseValue1' should write the int value 1 into variable var1
    Expression.SwitchCase(Expression.Assign(var1, Expression.Constant(1)), Expression.Constant("SwitchCaseValue1")),
    // the second case 'SwitchCaseValue2' should write the string value 'Example' into variable var2 
    Expression.SwitchCase(Expression.Assign(var2, Expression.Constant("Example")), Expression.Constant("SwitchCaseValue2"))
};

Expression.Switch(Expression.Constant("SwitchValue"), cases);

这会引发这种异常:All case bodies and the default body must have the same type.

我认为这指的是Assign为案例1返回一个int而对于案例2则返回一个字符串。 我怎么能一无所获?

如果我将var2更改为int:

// an int variable
var var1 = Expression.Parameter(typeof(int));
// a string variable
var var2 = Expression.Parameter(typeof(int));

var cases = new[] 
{ 
    // the first case 'SwitchCaseValue1' should write the int value 1 into variable var1
    Expression.SwitchCase(Expression.Assign(var1, Expression.Constant(1)), Expression.Constant("SwitchCaseValue1")),
    // the second case 'SwitchCaseValue2' should write the string value 'Example' into variable var2 
    Expression.SwitchCase(Expression.Assign(var2, Expression.Constant(2)), Expression.Constant("SwitchCaseValue2"))
};

Expression.Switch(Expression.Constant("SwitchValue"), cases);

它引发了异常:Default body must be supplied if case bodies are not System.Void.

所以我改变了:最后一行 Expression.Switch(Expression.Constant("SwitchValue"), Expression.Constant(0), cases);

这将编译。但不是我正在寻找的......

是否有其他方法可以修复此第一个解决方案,而无需执行额外的代码来返回相同的类型?

我不喜欢选择无意义的回报值等解决方案,例如:

// an int variable
var var1 = Expression.Parameter(typeof(int));
// a string variable
var var2 = Expression.Parameter(typeof(string));

var cases = new[] 
{ 
    // the first case 'SwitchCaseValue1' should write the int value 1 into variable var1
    Expression.SwitchCase(
        Expression.Block( 
            Expression.Assign(var1, Expression.Constant(1)), 
            // return a boolean
            Expression.Constant(true)), 
        Expression.Constant("SwitchCaseValue1")),
    // the second case 'SwitchCaseValue2' should write the string value 'Example' into variable var2 
    Expression.SwitchCase(
        Expression.Block( 
            Expression.Assign(var2, Expression.Constant("Example")), 
            // return a boolean
            Expression.Constant(true)), 
        Expression.Constant("SwitchCaseValue2"))
};


Expression.Switch(Expression.Constant("SwitchValue"), Expression.Constant(false), cases);

我理解表达式的逻辑并返回一个值。但有没有办法避免实现无意义的代码?

1 个答案:

答案 0 :(得分:4)

我自己找到了答案

Expression.Switch()有一个重载Switch(Type type, Expression switchValue, Expression defaultBody, MethodInfo comparison, IEnumerable<SwitchCase> cases);

使用此重载并将typeof(void)传递给参数type时,它会接受它。

msdn:“SwitchExpression对象中的所有SwitchCase对象必须具有相同的类型,除非SwitchExpression的类型为void。”我没有在 SwitchExpression类型之间建立连接< / em>和包含类型参数的重载。

这将完成这项工作:

// an int variable
var var1 = Expression.Parameter(typeof(int));
// a string variable
var var2 = Expression.Parameter(typeof(string));

var cases = new[] 
{ 
    // the first case 'SwitchCaseValue1' should write the int value 1 into variable var1
    Expression.SwitchCase(
            Expression.Assign(var1, Expression.Constant(1)), 
            Expression.Constant("SwitchCaseValue1")),
    // the second case 'SwitchCaseValue2' should write the string value 'Example' into variable var2 
    Expression.SwitchCase(
            Expression.Assign(var2, Expression.Constant("Example")), 
            Expression.Constant("SwitchCaseValue2"))
};

Expression.Switch(typeof(void), Expression.Constant("SwitchValue"), null, null, cases);