Implicit casting of Null-Coalescing operator result

孤人 提交于 2019-11-27 07:48:08

问题


With the following understanding about null coalescing operator (??) in C#.

int? input = -10;
int result = input ?? 10;//Case - I
//is same as:
int result = input == null? input : 10; // Case - II

While, by definition and usage, Case I and Case II are same.

It is surprising to see that in Case-I compiler is able to implicitly cast int? to int while in Case-II it shows error: 'Error 1 Cannot implicitly convert type 'int?' to 'int'"

What is it that I am missing about null-coalescing operator?

Thanks for your interest.


回答1:


To make the second case work with the ternary operator, you could use the following:

int result = input != null ? input.Value : 10;

The Value property of the Nullable<T> type returns the T value (in this case, the int).

Another option is to use Nullable<T>.HasValue:

int result = input.HasValue ? input.Value : 10;

The myNullableInt != null construct is only syntactic sugar for the above HasValue call.




回答2:


This behavior you have observed for the null-coalescing operator ?? is a documented language feature, see section 7.13 of the C# 4.0 Language Specification for more details.

The type of the expression a ?? b depends on which implicit conversions are available on the operands. In order of preference, the type of a ?? b is A0, A, or B, where A is the type of a (provided that a has a type), B is the type of b (provided that b has a type), and A0 is the underlying type of A if A is a nullable type, or A otherwise. Specifically, a ?? b is processed as follows:

  • If A exists and is not a nullable type or a reference type, a compile-time error occurs.

  • If b is a dynamic expression, the result type is dynamic. At run-time, a is first evaluated. If a is not null, a is converted to dynamic, and this becomes the result. Otherwise, b is evaluated, and this becomes the result.

  • Otherwise, if A exists and is a nullable type and an implicit conversion exists from b to A0, the result type is A0. At run-time, a is first evaluated. If a is not null, a is unwrapped to type A0, and this becomes the result. Otherwise, b is evaluated and converted to type A0, and this becomes the result.

  • Otherwise, if A exists and an implicit conversion exists from b to A, the result type is A. At run-time, a is first evaluated. If a is not null, a becomes the result. Otherwise, b is evaluated and converted to type A, and this becomes the result.

  • Otherwise, if b has a type B and an implicit conversion exists from a to B, the result type is B. At run-time, a is first evaluated. If a is not null, a is unwrapped to type A0 (if A exists and is nullable) and converted to type B, and this becomes the result. Otherwise, b is evaluated and becomes the result.

  • Otherwise, a and b are incompatible, and a compile-time error occurs.

See section 7.14 for why the conditional operator a ? b : c works differently.

Download the specification to read both in completeness at your leisure.




回答3:


int result = input == null ? input : 10;

You got your condition mixed in the second case - you probably meant:

int result = input != null ? input : 10;

Now this won't compile because both types in use with the ternary operator must be exactly identical (and int? is not the same as int) - you can use a simple cast as a solution:

int result = input != null ? (int)input : 10;



回答4:


A more concise explantion:

int? NULL_Int = 1;
int NORM_Int = 2;

NULL_Int = NORM_Int;  // OK

NORM_Int = NULL_Int;  // NO, you can't assign a null to an int


来源:https://stackoverflow.com/questions/8898223/implicit-casting-of-null-coalescing-operator-result

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!