Operador de propagação nula em C # 6.0 e atribuição de propriedades

Esta questão foi completamente revisada com o objetivo de ser minuciosa na explicação.

Observei o que parece ser uma limitação bastante ruim do operador de propagação nula no C # 6.0, no qual você não pode chamar propriedadesetters contra um objeto que tenha sido propagado nulo (embora você possa chamar propriedadegetters contra um objeto que tenha sido propagado nulo). Como você verá na IL gerada(que eu refleti em c #), não há nada que deva limitar a capacidade de chamar configuradores de propriedades usando propagação nula.

Para começar, criei uma classe simples, com os métodos Get / Set do estilo Java e uma propriedade com acesso público ao 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;
    }
}

Eu testei a capacidade de propagação nula na seguinte classe de teste.

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;
    }
}

O lado esquerdo de uma atribuição deve ser uma variável, propriedade ou indexador.

No entanto, você pode perceber que a maneira Java de definir o nome chamandoSetName(...) funciona, e você também pode perceber que obter o valor de uma propriedade propagada nula também funciona.

Vamos dar uma olhada no C # que foi gerado a partir deste 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;
}

Observe que, quando usado contra oSetName método, a propagação nula se transforma em um simplesif declaração e que, quando usado contra oName getter de propriedade, um operador ternário é usado para obter o valor deName ounull.

Uma coisa que notei aqui é a diferença de comportamento entre usar umif declaração e usando o operador ternário: ao usar um setter, usando umif A instrução funcionaria, enquanto o uso de um operador ternário não funcionaria.

public static void Main(string[] args)
{
    Person person = null;

    if (person != null)
    {
        person.Name = "John Smith";
    }

    person.Name = (person != null) ? "John Smith" : null;
}

Neste exemplo, estou usando tanto umif declaração e ao operador ternário para verificar se a pessoa estánull antes de tentar atribuir ao seuName propriedade. aif declaração funciona como esperado; a declaração usando o operador ternário falha, conforme o esperado

Referência de objeto não definida para uma instância de um objeto.

Na minha opinião, a limitação vem da capacidade do C # 6.0 de transformar a propagação nula em umif declaração ou uma expressão ternária. Se tivesse sido projetado para usar apenasif instruções, a atribuição de propriedade funcionaria via propagação nula.

Até agora, eu não vi um argumento convincente sobre o motivo de isso NÃO ser possível, portanto, ainda estou procurando respostas!

questionAnswers(3)

yourAnswerToTheQuestion