que para operador asignacion c# c#-6.0 null-conditional-operator

para - C#Operador de navegación segura: ¿qué está pasando realmente?



operador/= en c++ (3)

He estado siguiendo la característica de operador de navegación segura agregada en C # 6 con cierto interés. Lo he estado esperando por un tiempo. Pero estoy encontrando un comportamiento diferente del que esperaba. Me estoy dando cuenta de que realmente no entiendo cómo funciona realmente.

Dada esta clase

class Foo { public int? Measure; }

Aquí hay un código usando el nuevo operador.

Foo f = new Foo { Measure = 3 }; Console.WriteLine(f?.Measure); // 3 f = new Foo { Measure = null }; Console.WriteLine(f?.Measure); // null f = null; Console.WriteLine(f?.Measure); // null

Hasta aquí, todo está funcionando como se esperaba. ?. está accediendo a los miembros cuando el lado izquierdo no está nulo, de lo contrario, se vuelve nulo. Pero aquí las cosas van en una dirección que no esperaba.

var i = f?.Measure; // i is Nullable<int> Console.WriteLine(i.HasValue); // false Console.WriteLine(f?.Measure.HasValue); // null

¿Qué?

¿Por qué puedo obtener HasValue de i , pero no de la misma expresión que HasValue a i ? ¿Cómo puede HasValue ser nulo?

Edición: mi pregunta real es sobre el comportamiento del programa, no un error de compilación. Eliminé el contenido adicional sobre la compilación, y enfocé esta pregunta más estrechamente en por qué dos resultados diferentes son devueltos por lo que parece ser la misma lógica.


Vamos a caminar a través de esto lógicamente.

var f = ???; var i = f?.Measure; var t = i.HasValue;

No sabemos si f es nulo o no.

  1. Si f es nulo, entonces el resultado ( i ) es null
  2. Si f no es nulo, entonces el resultado ( i ) es un int

Por lo tanto, i se define como int? y t es un bool

Ahora, vamos a caminar a través de esto:

var f = ???; var i = f?.Measure.HasValue;

  1. Si f es nulo, entonces el resultado ( i ) es nulo
  2. Si f no es nulo, entonces el resultado ( i ) es Measure.HasValue , que es un bool.

Por lo tanto, i es un bool? .

Si f es nulo, cortocircuitamos y devolvemos nulo. Si no es así, devolvemos el resultado bool de .HasValue .

Esencialmente, cuando se usa ?. - el tipo de retorno debe ser un valor de referencia, o un Nullable<T> , ya que la expresión puede Nullable<T> un cortocircuito para devolver un valor nulo.


Nullable<T> es en realidad una estructura y, por lo tanto, no puede ser nulo, solo su Value puede, por lo que HasValue siempre estará accesible.


var i = f?.Measure; // i is Nullable<int> Console.WriteLine(i.HasValue); // false Console.WriteLine(f?.Measure.HasValue); // null

En este caso, f es nulo.

La razón por la que i.HasValue devolvió false es porque i es de tipo Nullable<int> . Entonces, incluso cuando el valor de i es nulo, como en este caso, i.HasValue sigue siendo accesible.

Sin embargo, f?.Measure.HasValue devuelve inmediatamente null después de f? es evaluado De ahí el resultado que ves arriba.

Solo para citar el comentario de Rob :

Lo principal a tener en cuenta es que estás leyendo y comprendiendo esto: f? .Meaure.HasValue como esto: (f? .Measure) .HasValue, que no es.