C # 6.0 Null-Propagationsoperator & Eigenschaftszuweisung

Diese Frage wurde im Interesse einer gründlichen Erklärung komplett überarbeitet.

Ich habe festgestellt, dass der Null-Propagierungsoperator in C # 6.0 anscheinend nur eine unzureichende Einschränkung aufweist, da Sie property @ nicht aufrufen könne Setter für ein Objekt, das nicht weitergegeben wurde (obwohl Sie property @ aufrufen könne getters für ein Objekt, das nicht weitergegeben wurde). Wie Sie an der generierten IL @ sehen werd (was ich in C # reflektiert habe), nichts sollte die Fähigkeit einschränken, Eigenschaftssetter mit Null-Propagierung aufzurufen.

unächst habe ich eine einfache Klasse erstellt, die sowohl Get / Set-Methoden im Java-Stil als auch eine Eigenschaft mit öffentlichem Get- / Setter-Zugriff enthäl

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

Ich habe die Fähigkeit der Null-Ausbreitung in der folgenden Testklasse getestet.

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

Die linke Seite einer Zuweisung muss eine Variable, eine Eigenschaft oder ein Indexer sein.

Sie können jedoch feststellen, dass die Java-Methode zum Festlegen des Namens durch Aufrufen vonSetName(...) funktioniert, und Sie stellen möglicherweise auch fest, dass das Abrufen des Werts einer durch Null propagierten Eigenschaft ebenfalls funktioniert.

Werfen wir einen Blick auf das C #, das aus diesem Code generiert wurde:

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

Bitte beachten Sie, dass bei Verwendung gegen dasSetName -Methode, Null-Propagierung verwandelt sich in ein einfachesif -Anweisung, und das bei Verwendung gegen dasName property getter, ein ternärer Operator wird verwendet, um entweder den Wert von @ zu erhaltName odernull.

Eine Sache, die ich hier bemerkt habe, ist der Verhaltensunterschied zwischen der Verwendung einesif -Anweisung und Verwendung des ternären Operators: Wenn Sie einen Setter verwenden, verwenden Sie einifie @ -Anweisung würde funktionieren, wohingegen die Verwendung eines ternären Operators nicht funktionieren würd

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

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

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

n diesem Beispiel verwende ich sowohl einif -Anweisung und der ternäre Operator, um zu prüfen, ob die Person @ inull vor dem Versuch, seinem @ zuzuweisName Eigentum. dasif Anweisung funktioniert wie erwartet; Die Anweisung mit dem ternären Operator schlägt erwartungsgemäß fehl

Der Objektverweis wurde nicht auf eine Instanz eines Objekts festgelegt

Meiner Meinung nach ergibt sich die Einschränkung aus der Fähigkeit von C # 6.0, die Nullpropagierung in ein @ umzuwandelif Anweisung oder ein ternärer Ausdruck. Wäre es so konzipiert, dass es nur @ verwendeif -Anweisungen, die Zuweisung von Eigenschaften würde über Null-Propagierung funktionieren.

Bisher habe ich kein überzeugendes Argument dafür gesehen, warum dies NICHT möglich sein SOLLTE, deshalb bin ich immer noch auf der Suche nach Antworten!

Antworten auf die Frage(6)

Ihre Antwort auf die Frage