问题
I'm struggling to build an expression that if the condition is true throws an exception and if it's false that it should return a value but I'm always getting the ArgumentException
:
var expr =
Expression.Condition(
Expression.Equal(Expression.Constant(0), Expression.Constant(0)),
Expression.Throw(Expression.Constant(new DivideByZeroException())),
Expression.Constant(1));
var lambda = Expression.Lambda<Func<int>>(expr);
var result = lambda.Compile()();
If I put Expression.Empty()
as the third argument of the Condition
it then runs but I don't get the desired result if the condition is false.
回答1:
This does it.
var expr =
Expression.Block(
Expression.IfThen(
Expression.Equal(Expression.Constant(1), Expression.Constant(1)),
Expression.Throw(
Expression.New(typeof(DivideByZeroException))
)
),
Expression.Constant(1)
);
var lambda = Expression.Lambda<Func<int>>(expr);
var result = lambda.Compile()();
Conditional
is more similar to the ternary operator. So what you were writing was more equivalent to in C#:
return (0 == 0) ? throw new DivideByZeroException() : 1;
I changed your constant exception to a dynamically created one, I'm assuming that is preferred.
回答2:
Conditional expressions must return the same type from each branch. What you're trying is equivalent to
var x = 0==0 ? throw new DivideByZeroException() : 1;
which is not valid. You could just cause a DivideByZeroException
:
var expr =
Expression.Condition(
Expression.Equal(Expression.Constant(0), Expression.Constant(0)),
Expression.Divide(Expression.Constant(1), Expression.Constant(0)),
Expression.Constant(1));
回答3:
Simply create a method that throws the exception for you, and has whatever type you want:
public static T ThrowHelper<T>(Exception e)
{
throw e;
}
Then create an expression that is calling that method. This makes the act of throwing an expression an expression, rather than a statement, and allows that expression to have whatever type you want:
var throwMethod = typeof(TheClassThrowIsIn)
.GetMethod("ThrowHelper", BindingFlags.Static)
.MakeGenericMethod(typeof(int));
var expr =
Expression.Condition(
Expression.Equal(Expression.Constant(0), Expression.Constant(0)),
Expression.Call(throwMethod, Expression.Constant(new DivideByZeroException())),
Expression.Constant(1));
来源:https://stackoverflow.com/questions/34773933/how-can-i-create-an-expression-that-either-throws-an-exception-or-returns-a-valu