C # 6.0 Operador de propagación nulo y asignación de propiedades

Esta pregunta ha sido completamente revisada en aras de una explicación exhaustiva.

He notado lo que parece ser una limitación bastante pobre del operador de propagación nula en C # 6.0 en que no se puede llamar a la propiedadsetters contra un objeto que se ha propagado nulo (aunque puede llamar a la propiedadcaptadores contra un objeto que se ha propagado nulo). Como verás 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 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 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, propiedad o indexador.

Sin embargo, puede observar a partir de esto que la forma Java de establecer el nombre, llamandoSetName(...) funciona, y también puede notar que obtener el valor de una propiedad propagada nula también funciona.

Echemos un vistazo al 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 elSetName método, la propagación nula se transforma en un sencilloif declaración, y que cuando se usa contra elName getter de propiedad, un operador ternario se utiliza para obtener el valor deName onull.

Una cosa que he notado aquí es la diferencia de comportamiento entre usar unif y utilizando el operador ternario: cuando se usa un setter, se usa unif la declaración funcionaría, mientras que usar un operador ternario no lo haría.

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 tanto unif declaración y el operador ternario para verificar si la persona esnull antes de intentar asignar a suName propiedad. elif la declaración funciona como se esperaba; 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 unif declaración o una expresión ternaria. Si hubiera sido diseñado para usar soloif declaraciones, la asignación de propiedad funcionaría a través de 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.

Respuestas a la pregunta(3)

Su respuesta a la pregunta