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()devuelveFoo, ¿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().