Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

null conditional operator not working with nullable types?

I'm writing a piece of code in c#6 and for some strange reason this works

var value = objectThatMayBeNull?.property; 

but this doesn't:

int value = nullableInt?.Value; 

By not works I mean I get a compile error saying Cannot resolve symbol 'Value'. Any idea why the null conditional operator ?. isn't working?

like image 595
linkerro Avatar asked Aug 04 '15 13:08

linkerro


People also ask

What is null conditional operator in C#?

Null-conditional operators ?. and ?[] Available in C# 6 and later, a null-conditional operator applies a member access, ?. , or element access, ?[] , operation to its operand only if that operand evaluates to non-null; otherwise, it returns null . That is, If a evaluates to null , the result of a?. x or a?[x] is null .

Which operator is used with null operator?

The ?? operator is used to check null values and you can also assign a default value to a variable whose value is null(or nullable type).

What is null conditional and null-coalescing in C#?

it is used to define a default value for nullable value types or reference types. It returns the left-hand operand if the operand is not null; otherwise, it returns the right operand. In cases where a statement could return null, the null-coalescing operator can be used to ensure a reasonable value gets returned.

What is Elvis operator in C#?

In certain computer programming languages, the Elvis operator, often written ?: , or or || , is a binary operator that returns its first operand if that operand evaluates to a true value, and otherwise evaluates and returns its second operand.


2 Answers

Okay, I have done some thinking and testing. This is what happens:

int value = nullableInt?.Value; 

Gives this error message when compiling:

Type 'int' does not contain a definition for `Value'

That means that ? 'converts' the int? into the actual int value. This is effectively the same as:

int value = nullableInt ?? default(int); 

The result is an integer, which doesn't have a Value, obviously.

Okay, might this help?

int value = nullableInt?; 

No, that syntax isn't allowed.

So what then? Just keep using .GetValueOrDefault() for this case.

int value = nullableInt.GetValueOrDefault(); 
like image 160
Patrick Hofman Avatar answered Sep 29 '22 03:09

Patrick Hofman


The reason for this is that accessing the value with a null conditional operator would be pointless:

  • When you apply x?.p where p is a non-nullable value type T, the result is of type T?. By the same token, the result of nullableInt?.Value operation must be nullable.
  • When your Nullable<T> has a value, the result of nullableInt?.Value would be the same as the value itself
  • When your Nullable<T> does not have a value, the result would be null, which is, again, the same as the value itself.

Although it does not make sense to access Value with the ?. operator, it does make sense to access other properties of nullable value types. The operator works consistently with nullable value types and with reference types, so these two implementations produce identical behavior:

class PointClass {     public int X { get; }     public int Y { get; }     public PointClass(int x, int y) { X = x; Y = y; } } struct PointStruct {     public int X { get; }     public int Y { get; }     public PointStruct(int x, int y) { X = x; Y = y; } } ... PointClass pc = ... PointStruct? ps = ... int? x = pc?.X; int? y = ps?.Y; 

In case of a nullable struct the operator lets you access a property of the underlying type PointStruct, and it adds nullability to the result in the same way that it does for non-nullable properties of the reference type PointClass.

like image 22
Sergey Kalinichenko Avatar answered Sep 29 '22 03:09

Sergey Kalinichenko