Reputation: 22038
I'm trying to implement the Expression.Switch()
to create a switch statement within my expressions. I'm struggling with some issues.
I've created a small example that raises the exception. The switch uses a string to switch the cases and within that case it will assign a variable.
Here is some code that will raise the exception:
// 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);
This will raise this excepion: All case bodies and the default body must have the same type.
I think this refers to the Assign
returning for case 1 an int and for case 2 a string. How can i return nothing?
If I change the var2
to type 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);
It raises exception: Default body must be supplied if case bodies are not System.Void.
So i changed: the last line to
Expression.Switch(Expression.Constant("SwitchValue"), Expression.Constant(0), cases);
This will compile. but is not what I'm looking for...
Is there another way to fix this first solution without implementing extra code to return the same type?
I don't like solutions like selecting a meaningless return value, like:
// 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);
I understand the logic of Expressions and returning a value. But is there a way to avoid implementing meaningless code?
Upvotes: 4
Views: 776
Reputation: 22038
I found the answer myself
The Expression.Switch()
has an overload Switch(Type type, Expression switchValue, Expression defaultBody, MethodInfo comparison, IEnumerable<SwitchCase> cases);
When using this overload and passing typeof(void)
into the parameter type
, it will accept it.
msdn: "All SwitchCase objects in a SwitchExpression object must have the same type, unless the SwitchExpression has the type void." I didn't make the connection between the SwitchExpression type and an overload containing a type parameter.
This will do the job:
// 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);
Upvotes: 6