c# - operador de propagacion javascript
C#6.0 Operador de propagaciĆ³n nula y asignaciĆ³n de propiedad (3)
¡No eres el único! SLaks planteó esto como un problema
¿Por qué no puedo escribir código como este?
Process.GetProcessById(2)?.Exited += delegate { };
y luego se cerró brevemente como "Por diseño".
la ?. El operador nunca produce un valor, por lo que es por diseño.
alguien comentó que sería bueno para los establecedores de propiedades, así como para los manejadores de eventos
Tal vez agregue también establecedores de propiedades en la solicitud como:
Object?.Prop = false;
y se volvió a abrir como una solicitud de función para C # 7.
Esta pregunta ha sido completamente revisada con el fin de ser exhaustiva en la explicación.
Me he dado cuenta de lo que parece ser una limitación bastante pobre del operador de propagación nula en C # 6.0 en el sentido de que no puede llamar a los establecedores de propiedades contra un objeto que ha sido propagado nulo (aunque puede llamar a los captadores de propiedades contra un objeto que ha sido propagado nulo) . Como verá en la IL generada (que he reflejado en C #) , no hay nada que deba limitar la capacidad de llamar a los establecedores de propiedades mediante la propagación nula.
Para empezar, he creado una clase simple, con métodos Get / Set de estilo Java y una propiedad con acceso público a getter / setter.
public class Person
{
public Person(string name, DateTime birthday)
{
Name = name;
}
public string Name { get; set; }
public void SetName(string name)
{
Name = name;
}
public string GetName()
{
return Name;
}
}
He probado la capacidad de propagación nula en la siguiente clase de prueba.
public class Program
{
public static void Main(string[] args)
{
Person person = new Person("Joe Bloggs", DateTime.Parse("01/01/1991"));
// This line doesn''t work - see documented error below
person?.Name = "John Smith";
person?.SetName("John Smith");
string name = person?.Name;
}
}
El lado izquierdo de una asignación debe ser una variable, una propiedad o un indexador.
Sin embargo, puede observar en esto que la forma Java de establecer el nombre, al llamar a SetName(...)
funciona, y también puede notar que el valor de una propiedad propagada nula también funciona.
Echemos un vistazo a la C # que se generó a partir de este código:
public static void Main(string[] args)
{
Person person = new Person("Joe Bloggs", DateTime.Parse("01/01/1991"));
if (person != null)
{
person.SetName("John Smith");
}
string arg_33_0 = (person != null) ? person.Name : null;
}
Tenga en cuenta que cuando se usa contra el método SetName
, la propagación nula se transforma en una instrucción if
directa, y que cuando se usa contra el captador de propiedades Name
, se usa un operador ternario para obtener el valor de Name
o null
.
Una cosa que he notado aquí es la diferencia de comportamiento entre usar una instrucción if
y usar el operador ternario: cuando se usa un setter, usar una instrucción if
podría funcionar, mientras que usar un operador ternario no.
public static void Main(string[] args)
{
Person person = null;
if (person != null)
{
person.Name = "John Smith";
}
person.Name = (person != null) ? "John Smith" : null;
}
En este ejemplo, estoy usando una instrucción if
y el operador ternario para verificar si la persona es null
antes de intentar asignar su propiedad de Name
. la sentencia if
funciona como se espera; la declaración que usa el operador ternario falla, como se esperaba
Referencia a objeto no establecida como instancia de un objeto.
En mi opinión, la limitación proviene de la capacidad de C # 6.0 para transformar la propagación nula en una sentencia if
o una expresión ternaria. Si hubiera sido diseñado para usarse solo en sentencias, la asignación de propiedades funcionaría mediante propagación nula.
Hasta ahora, no he visto un argumento convincente de por qué esto NO DEBE ser posible, por lo tanto, ¡todavía estoy buscando respuestas!
No se puede usar el operador de propagación nula de esta manera.
Este operador permite propagar nulos mientras evalúa una expresión. No se puede usar como objetivo de una asignación exactamente como sugiere el error.
Necesitas apegarte a la simple comprobación nula:
if (a != null)
{
a.Value = someValue;
}
Pruébalo así ...
using System;
namespace TestCon
{
class Program
{
public static void Main()
{
Person person = null;
//Person person = new Person() { Name = "Jack" };
//Using an "if" null check.
if (person != null)
{
Console.WriteLine(person.Name);
person.Name = "Jane";
Console.WriteLine(person.Name);
}
//using a ternary null check.
string arg = (person != null) ? person.Name = "John" : arg = null;
//Remember the first statment after the "?" is what happens when true. False after the ":". (Just saying "john" is not enough)
//Console.WriteLine(person.Name);
if (arg == null)
{
Console.WriteLine("arg is null");
}
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
public class Person
{
public string Name { get; set; }
}
}