Expression.Condition: Argument types do not match

c# expression-trees ternary-operator

Question

I'm attempting to make this using an expression:

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

I'm usingbool.Parse("true") simply to prevent Visual Studio (VS) from warning about inaccessible code pathstrue When I express myself in writing like way...

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

I experience the errorArgument types do not match . I altered my expression to this since I'm quite sure I know what's going on:

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

Although it is effective, I can't claim that I like writing a statement that is this:

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

Can this ternary expression be made to function without generating a new instance ofint? ? In my particular example, c# creates a new instance automatically, so maybe this is acceptable?

Edit

Please take notice that I exclusively useExpression.Constant() to simulate a value returned by aMethodCallExpression to make my code sample simpler. Therefore, anything that suggests using constant values as a fix won't work here.

1
2
10/26/2015 1:44:44 PM

Accepted Answer

Instead of generating an instance, you may generate a cast usingnew , i.e.

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

as in this:

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

Demo.

4
10/26/2015 1:23:02 PM

Popular Answer

Enter the constant expression as follows:

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

Alternately, enter the conditional statement as follows:

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

Initial changes the operation of the constant (in both instances, the value is kept as a boxedint similar to how it would be for anint consistent, and if necessary, the unpacking is toint? .

The second causes the type that both operands must be cast to be stored in the condition itself.

Keep in mind that, particularly with the first two, there may not really be any casting. For example, if you compile, you are likely to compile to a form that operates onint? directly, therefore the produced code it generates does not need a cast, while the expression object would.

Also keep in mind that the last option may not be accessible since certain providers cannot handle typed circumstances. E.g.EnumerableQuery can't handle them (see https://github.com/dotnet/corefx/issues/3607).



Related Questions





Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow