Search code examples
c#expression-treesternary-operator

Expression.Condition: Argument types do not match


I am trying to use an expression to create this:

bool.Parse("true") ? default(int?) : 1

BTW, I'm using bool.Parse("true") just to keep VS from complaining about unreachable code paths, so just assume it uses a constant true. When I write my expression like this...

Expression.Condition(Expression.Constant(true), Expression.Default(typeof(int?)),
    Expression.Constant(1))

...I get the error Argument types do not match. I am pretty certain that I'm aware of what's happening, so I changed my expression to do this:

Expression.Condition(Expression.Constant(true), Expression.Default(typeof(int?)),
    Expression.New(typeof(int?).GetConstructor(new[] { typeof(int) }), Expression.Constant(1)));

It works, but I can't say I like writing an expression that's the equivalent of this:

bool.Parse("true") ? default(int?) : new int?(1)

Is there a way to get this ternary expression to work without creating a new instance of int?? Perhaps it's okay to do this because c# is implicitly creating a new instance in my concrete example anyway?

Edit

I should note that I am only using Expression.Constant() to emulate a return value from a MethodCallExpression in order to simplify my code example. Therefore, anything suggesting the use of constant values as a solution will not work in this case.


Solution

  • You can create a cast instead of creating an instance with new, i.e.

    bool.Parse("true") ? default(int?) : (int?)(1)
    

    like this:

    Expression.Condition(
        Expression.Constant(true)
    ,   Expression.Default(typeof(int?))
    ,   Expression.Convert(Expression.Constant(1), typeof(int?))
    )
    

    Demo.