Aki*_*kim 5 c# codedom null-coalescing-operator
比方说,我有以下简化类型:
public class Model
{
public decimal? Result { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
如何使用CodeDOM表示空合并运算符来生成C#代码,它有可能吗?现在我正在使用以下解决方法:
new CodePropertyReferenceExpression(
new CodePropertyReferenceExpression(modelArgument, "Result"),
"Value"))
Run Code Online (Sandbox Code Playgroud)
这等于model.Result.Value,但不是model.Result ?? 0M
CodeExpressionequalent到model.Result.GetValueOrDefault(0M)适合于空值类型
new CodeMethodInvokeExpression(
new CodeMethodReferenceExpression(
new CodePropertyReferenceExpression(modelArgument, "Result"),
"GetValueOrDefault"),
new [] { new CodePrimitiveExpression(0m) })),
Run Code Online (Sandbox Code Playgroud)
正如评论部分提到的,??运算符只是一个语法糖。如果您检查IL代码,您将看到条件HasValue,然后调用GetValueOrDefault方法。该方法接受一个参数,如果 Nullable 对象没有值,则返回该参数,否则返回Value属性。
尝试使用下一个代码,它只是调用 GetValueOrDefault方法 via CodeMethodInvokeExpression,这在语义上等同于空合并运算符的调用。我使用4作为默认值,但在您的情况下,省略该参数即可完成工作,因为您需要0m作为小数的默认值。
new CodeMethodInvokeExpression(
new CodeMethodReferenceExpression(
new CodePropertyReferenceExpression(modelArgument, "Result"),
"GetValueOrDefault"),
new [] { new CodePrimitiveExpression(0m) }));
Run Code Online (Sandbox Code Playgroud)
注意:经过检查GetValueOrDefault我发现,它使用了HasValue属性。因此不需要调用它两次(因此,如果使用??未经优化的运算符,编译器将调用它两次。如果启用优化,它将简单地调用GetValueOrDefault)。方法内容如下:
public T GetValueOrDefault(T defaultValue)
{
if (!this.HasValue)
return defaultValue;
else
return this.value;
}
Run Code Online (Sandbox Code Playgroud)