Let's say, I have following simplified type:
public class Model
{
public decimal? Result { get; set; }
}
How to express null coalescing operator using CodeDOM to generate C# code, is it possible at all? Now I'm using following workaround:
new CodePropertyReferenceExpression(
new CodePropertyReferenceExpression(modelArgument, "Result"),
"Value"))
Which is equal to model.Result.Value
, but not model.Result ?? 0M
CodeExpression
equalent to model.Result.GetValueOrDefault(0M)
suitable for nullable value types
new CodeMethodInvokeExpression(
new CodeMethodReferenceExpression(
new CodePropertyReferenceExpression(modelArgument, "Result"),
"GetValueOrDefault"),
new [] { new CodePrimitiveExpression(0m) })),
As guys mentioned in the comment section, ??
operator is just a syntactical sugar. If you inspect IL
code you will see condition on HasValue
and then call to a GetValueOrDefault
method. This method accepts a parameter, that will be returned if a Nullable object has no value, in other case it will return Value
property.
Try to use next code, that simply call GetValueOrDefault
method via CodeMethodInvokeExpression
, which is semantically equivalent to the call of null-coallesing operator. I use 4
as a default value, but in you case omiting the parameter will do the job, because you demand 0m
as a default value for a decimal.
new CodeMethodInvokeExpression(
new CodeMethodReferenceExpression(
new CodePropertyReferenceExpression(modelArgument, "Result"),
"GetValueOrDefault"),
new [] { new CodePrimitiveExpression(0m) }));
Note: after inspection of GetValueOrDefault
I found, that it uses HasValue
property. So there is no need to call it twice (so compiler will call it twice in case of using ??
operator without optimization. In case of optimization enabled it will simply call GetValueOrDefault
). Method contents are given below:
public T GetValueOrDefault(T defaultValue)
{
if (!this.HasValue)
return defaultValue;
else
return this.value;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With