Implicit casting of Null-Coalescing statement result

Having the following view of the 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 use, the cases I and case II are the same.

Is it surprising to see that in Case-I the compiler is capable of implicitly throwing int? int, and in Case-II, an error: "Error 1 Cannot implicitly convert the type to" int "? to 'int'"

What am I missing in a zero-coalescent operation?

Thank you for your interest.

+6
source share
4 answers

For the second case to work with the ternary operator, you can use the following:

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

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

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

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

The myNullableInt != null construct is just the syntax sugar for the above HasValue call.

+5
source

Such behavior that you observed for the operator with zero coalescing ?? , is a documented language feature, see section 7.13 C # 4.0 Language Specifications for more details.

Type of expression a? b depends on what implicit conversions are available on the operands. In order of preference, type a? b is A0, A or B, where A is a type a (provided that a has a type), B is a type b (provided that b is a type), and A0 is the base type A if A is a null type, or otherwise. In particular, b is processed as follows:

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

  • If b is a dynamic expression, the type of the result is dynamic. At runtime, 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 null type, and there is an implicit conversion from b to A0, the result is A0. At runtime, it is first evaluated. If a is not null, a unfolds for 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 there is an implicit conversion from b to A, then the result 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 is of type B and there is an implicit conversion from a to B, then the result is B. At run time, a is first evaluated. If it is not null, a is expanded for type A0 (if A exists and is NULL) 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, why the conditional operator a ? b : c a ? b : c works differently.

Download the spec to read as completeness at your leisure.

+5
source
 int result = input == null ? input : 10; 

In the second case, you are confusing your state - you probably meant:

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

Now this will not compile, because both types used with the ternary operator must be exactly identical (and int? Does not match int ) - you can use a simple cast as a solution:

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

More concise explanation:

 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 
-1
source

Source: https://habr.com/ru/post/906217/


All Articles