uso signos puntuacion puntos punto parentesis ejemplos corchetes coma c# nullable

c# - puntos - signos de puntuacion



¿Por qué C#requiere paréntesis cuando se usan elementos nulables en una expresión? (2)

¿Alguien podría explicarme por qué se necesitan los paréntesis?

Porque Identity() devuelve un Foo (¿no es un Foo? ) Y, por lo tanto, no tiene ninguna propiedad Value . Si foo es nulo, el nulo se propagará a través de la llamada de Identity .

Cuando coloca paréntesis alrededor, los resultados de la expresión son Nullable<Foo> que tiene una propiedad Value .

También tenga en cuenta que si foo es nulo, estará llamando a Value en un Nullable<Foo> que no tiene ningún valor, y obtendrá una excepción en tiempo de ejecución . Algunos analizadores estáticos reconocerán que tiene una posible excepción de referencia nula esperando a suceder y le avisará.

Si los expandes a sus equivalentes sin propagación nula, será más claro:

Foo foo1; if(foo != null) { foo1 = foo.Identity().Value; // not possible - Foo has no Value property. } else { foo1 = null; // also not possible } Foo foo2; Foo? temp; if(foo != null) { temp = foo.Identity(); } else { temp = null; // actually a Nullable<Foo> with no value } foo2 = temp.Value; // legal, but will throw an exception at run-time if foo is null

Si Identity() devuelve Foo , ¿por qué Foo foo3 = foo?.Identity(); no compilar?

El equivalente de eso sería:

Foo foo3 if(foo != null) { foo3 = foo.Identity(); } else { foo3 = null; // not possible }

Soy nuevo en C # y mientras exploraba las características del lenguaje, encontré algo extraño:

struct Foo { public Foo Identity() { return this; } public static void Bar(Foo? foo) { Foo foo1 = foo?.Identity().Value; // Does not compile Foo foo2 = (foo?.Identity()).Value; // Compiles } }

¿Alguien podría explicarme por qué se necesitan los paréntesis?


Creo que fue una buena decisión del equipo c # para hacerlo de esta manera. Considere el siguiente escenario:

Si la estructura fue:

struct Foo { public int ID { set; get; } public Foo Identity() { return this; } public static void Bar(Foo? foo) { int? foo1 = foo?.Identity().ID; // compile Foo foo2 = (foo?.Identity()).Value; // Compiles } }

Si no necesita el paréntesis para acceder al resultado Nullable, no podrá acceder a la propiedad ID . Dado que a continuación no se compilará:

int? foo2 = (foo?.Identity()).GetValueOrDefault()?.ID

Cuando escribes foo?.Identity(). que es después de . es del tipo Foo devuelto por Identity() . Sin embargo, en (foo?.Identity()). que es después de . es Foo? que es el resultado real de toda la declaración foo?.Identity().