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

本文关键字:合并 运算符 表示 何使用 CodeDOM | 更新日期: 2023-09-27 18:08:28

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

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.GetValueOrDefault(0M)适合可空值类型

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

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

正如大家在评论部分提到的,??运算符只是一个语法糖。如果你检查IL代码,你会看到HasValue的条件,然后调用GetValueOrDefault方法。该方法接受一个参数,如果Nullable对象没有值,则返回该参数,在其他情况下,它将返回Value属性。

尝试使用下一个代码,即通过CodeMethodInvokeExpression调用GetValueOrDefault方法,这在语义上相当于调用null- colesing操作符。我使用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;
}