C# 如何使用CodeDOM表示空合并运算符?

C# 如何使用CodeDOM表示空合并运算符?,c#,codedom,null-coalescing-operator,C#,Codedom,Null Coalescing Operator,比方说,我有以下简化类型: public class Model { public decimal? Result { get; set; } } 如何使用CodeDOM来表示空合并操作符来生成C#代码,可能吗? 现在,我使用以下变通方法: new CodePropertyReferenceExpression( new CodePropertyReferenceExpression(modelArgument, "Result"), &qu

比方说,我有以下简化类型:

public class Model
{
    public decimal? Result { get; set; }
}
如何使用CodeDOM来表示空合并操作符来生成C#代码,可能吗? 现在,我使用以下变通方法:

new CodePropertyReferenceExpression(
    new CodePropertyReferenceExpression(modelArgument, "Result"),
        "Value"))
它等于
model.Result.Value
,但不等于
model.Result??0M

更好的解决办法
CodeExpression
等同于
model.Result.getValuerDefault(0M)
适用于可为空的值类型

new CodeMethodInvokeExpression(
                        new CodeMethodReferenceExpression(
                            new CodePropertyReferenceExpression(modelArgument, "Result"),
                            "GetValueOrDefault"),
                            new [] { new CodePrimitiveExpression(0m) })),

正如大家在评论部分提到的,
??
操作符只是一个语法糖。如果检查
IL
代码,您将看到
HasValue
上的条件,然后调用
GetValueOrDefault
方法。此方法接受一个参数,如果可为null的对象没有值,则将返回该参数,在其他情况下,它将返回
value
property

尝试使用下一个代码,即通过
codemethodinvokeeexpression
调用
GetValueOrDefault
方法,这在语义上等同于调用null coalesing操作符。我使用
4
作为默认值,但在您的情况下,省略该参数就可以了,因为您要求将
0m
作为十进制的默认值

new CodeMethodInvokeExpression(
                        new CodeMethodReferenceExpression(
                            new CodePropertyReferenceExpression(modelArgument, "Result"),
                            "GetValueOrDefault"),
                            new [] { new CodePrimitiveExpression(0m) }));
注意:在检查
GetValueOrDefault
之后,我发现它使用了
HasValue
属性。因此无需调用它两次(因此,如果使用未经优化的
运算符,编译器将调用它两次。如果启用了优化,则只需调用
GetValueOrDefault
)。方法内容如下:

public T GetValueOrDefault(T defaultValue)
{
  if (!this.HasValue)
    return defaultValue;
  else
    return this.value;
}

想一想,你有没有试过用一个空合并操作符编写一个简单的POCO,并查看在IL Dasm或reflector中生成的代码?@RussC我试过了。
model.Result??0M
与model.Result.HasValue相同吗?model.Result.getValuerDefault():0M我想可能是这样的;空合并只是一个编译器技巧;这应该会给你一个更好的线索,关于发射什么。从我所读到的内容来看,与其让一个发出三元运算符(这似乎是不允许的)发出一个If..Else块,不如基于以下链接:为什么不直接使用
model.Result.GetValueOrDefault()
?或者您还需要支持其他默认值吗?