Expression.Condition:参数类型不匹配

时间:2015-10-26 13:04:27

标签: c# expression-trees ternary-operator

我正在尝试使用表达式来创建它:

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

BTW,我正在使用bool.Parse("true")来阻止VS抱怨无法访问的代码路径,所以假设它使用常量true。当我写这样的表达时......

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

...我收到错误Argument types do not match。我很确定我知道发生了什么,所以我改变了表达方式来做到这一点:

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

它有效,但我不能说我喜欢写一个与此相当的表达式:

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

有没有办法让这个三元表达式工作而不创建int?的新实例?也许这样做是可以的,因为c#在我的具体例子中隐含地创建了一个新实例?

修改

我应该注意,我只使用Expression.Constant()来模拟MethodCallExpression的返回值,以简化我的代码示例。因此,任何暗示使用常数值作为解决方案的东西在这种情况下都不起作用。

3 个答案:

答案 0 :(得分:4)

您可以创建强制转换而不是使用bool.Parse("true") ? default(int?) : (int?)(1) 创建实例,即

Expression.Condition(
    Expression.Constant(true)
,   Expression.Default(typeof(int?))
,   Expression.Convert(Expression.Constant(1), typeof(int?))
)
像这样:

@media (min-width: 768px){
    .banner.lifest{
        height: 500px;
    }
}

@media (min-width: 992px){
    .banner.lifest{
    height: 740px;
    }
}

Demo.

答案 1 :(得分:1)

当你写bool.Parse("true") ? default(int?) : 1时,它实际上被编译成更类似于:

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

那么为什么不使用值为int?的常量1,如下所示:

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

Expression.Constant的重叠必须用作传递int?作为object将基础intnull框,您必须明确说它是int?常数。

答案 2 :(得分:1)

使用:

键入常量表达式
Expression.Condition(Expression.Constant(true), 
  Expression.Default(typeof(int?)), 
  Expression.Constant(1, typeof(int?)))

或者使用:

键入条件表达式
Expression.Condition(Expression.Constant(true), 
  Expression.Default(typeof(int?)), 
  Expression.Constant(1),
  typeof(int?))

第一个更改常量的工作方式(在两种情况下,值都存储为方框int,就像int常量一样,如果需要,则取消装箱是int?

第二个使条件本身存储两个操作数都必须转换为的类型。

请注意,可能没有任何实际的投射,尤其是前两个,例如如果你编译,你可能会编译成一个直接作用于int?的表单,所以虽然表达式对象需要一个强制转换来处理,但它生成的编译代码却没有。

另请注意,某些提供商无法处理类型条件,因此最后一个选项不可用。例如。 EnumerableQuery无法处理它们(请参阅https://github.com/dotnet/corefx/issues/3607)。