Versions- und Updateüberlegungen für C#-Entwickler

Kompatibilität ist ein wichtiges Ziel, wenn der Sprache C# neue Features hinzugefügt werden. In nahezu allen Fällen kann vorhandener Code problemlos mit einer neuen Compilerversion neu kompiliert werden. Das .NET-Runtimeteam hat auch das Ziel, die Kompatibilität für aktualisierte Bibliotheken sicherzustellen. Wenn Ihre App von einer aktualisierten Runtime mit aktualisierten Bibliotheken gestartet wird, ist das Verhalten in fast allen Fällen genau dasselbe wie bei früheren Versionen.

Die Sprachversion, die zum Kompilieren Ihrer App verwendet wird, entspricht in der Regel dem Runtimezielframeworkmoniker (TFM), auf den in Ihrem Projekt verwiesen wird. Weitere Informationen zum Ändern der Standardsprachversion finden Sie im Artikel Konfigurieren Ihrer Sprachversion. Dieses Standardverhalten sorgt für maximale Kompatibilität.

Wenn Breaking Changes eingeführt werden, werden sie wie folgt klassifiziert:

  • Binärer Breaking Change: Ein binärer Breaking Change verursacht ein anderes Verhalten in Ihrer Anwendung oder Bibliothek (möglicherweise sogar zu einem Absturz), wenn sie mit einer neuen Runtime gestartet wird. Sie müssen Ihre App neu kompilieren, um diese Änderungen zu integrieren. Die vorhandene Binärdatei funktioniert nicht ordnungsgemäß.
  • Breaking Change der Quelle: Ein Breaking Change der Quelle ändert die Bedeutung Ihres Quellcodes. Sie müssen Quellcodebearbeitungen vornehmen, bevor Sie Ihre Anwendung mit der neuesten Sprachversion kompilieren. Ihre vorhandene Binärdatei wird ordnungsgemäß mit dem neueren Host und der neueren Runtime ausgeführt. Beachten Sie, dass ein Breaking Change der Quelle für die Sprachsyntax auch eine Verhaltensänderung ist, wie in den Breaking Changes der Runtime definiert.

Wenn sich ein binärer Breaking Change auf Ihre App auswirkt, müssen Sie Ihre App neu kompilieren, aber sie müssen keinen Quellcode bearbeiten. Wenn sich ein Breaking Change der Quelle auf Ihre App auswirkt, wird die vorhandene Binärdatei weiterhin ordnungsgemäß in Umgebungen mit der aktualisierten Runtime und den aktualisierten Bibliotheken ausgeführt. Sie müssen jedoch Quelländerungen vornehmen, um mit der neuen Sprachversion und Runtime erneut zu kompilieren. Wenn sowohl ein Breaking Change der Quelle als auch ein binärer Breaking Change vorgenommen werden, müssen Sie Ihre Anwendung mit der neuesten Version erneut kompilieren und Quellupdates durchführen.

Aufgrund des Ziels, Breaking Changes durch das C#-Sprachteam und das Runtimeteam zu vermeiden, ist das Aktualisieren Ihrer Anwendung in der Regel eine Frage der Aktualisierung des TFM und der Neuerstellung der App. Bei öffentlich verteilten Bibliotheken sollten Sie jedoch Ihre Richtlinien für unterstützte TFMs und unterstützte Sprachversionen sorgfältig prüfen. Sie erstellen möglicherweise eine neue Bibliothek mit Features, die sich in der neuesten Version befinden, und müssen sicherstellen, dass Apps, die mit früheren Versionen des Compilers erstellt wurden, diese verwenden können. Alternativ können Sie ein Upgrade einer vorhandenen Bibliothek vornehmen, und viele Ihrer Benutzer*innen verfügen möglicherweise noch nicht über Versionen mit dem Upgrade.

Einführung von Breaking Changes in Ihren Bibliotheken

Wenn Sie neue Sprachfeatures in der öffentlichen API Ihrer Bibliothek einführen, sollten Sie abwägen, ob die Einführung des Features für die Benutzer*innen Ihrer Bibliothek entweder einen binären Breaking Change oder einen Breaking Change der Quelle bedeutet. Alle Änderungen an Ihrer internen Implementierung, die nicht in den public- oder protected-Schnittstellen angezeigt werden, sind kompatibel.

Hinweis

Wenn Sie die System.Runtime.CompilerServices.InternalsVisibleToAttribute verwenden, um Typen zum Anzeigen interner Member zu aktivieren, können die internen Member Breaking Changes einführen.

Einebinärer Breaking Change erfordert, dass Ihre Benutzer*innen ihren Code erneut kompilieren, um die neue Version verwenden zu können. Betrachten Sie beispielsweise diese öffentliche Methode:

public double CalculateSquare(double value) => value * value;

Wenn Sie der Methode den in-Modifizierer hinzufügen, ist dies ein binärer Breaking Change:

public double CalculateSquare(in double value) => value * value;

Benutzer*innen müssen jede Anwendung, die die CalculateSquare-Methode verwendet, neu kompilieren, damit die neue Bibliothek ordnungsgemäß funktioniert.

Ein Breaking Change der Quelle erfordert, dass Ihre Benutzer*innen ihren Code ändern, bevor sie erneut kompilieren. Betrachten Sie beispielsweise diesen Typ:

public class Person
{
    public string FirstName { get; }
    public string LastName { get; }

    public Person(string firstName, string lastName) => (FirstName, LastName) = (firstName, lastName);

    // other details omitted
}

In einer neueren Version möchten Sie die für record-Typen generierten synthetisierten Member nutzen. Sie nehmen die folgende Änderung vor:

public record class Person(string FirstName, string LastName);

Die vorherige Änderung erfordert Änderungen für jeden von Person abgeleiteten Typ. Alle diese Deklarationen müssen ihren Deklarationen den record-Modifizierer hinzufügen.

Auswirkungen von Breaking Changes

Wenn Sie Ihrer Bibliothek einen binären Breaking Change hinzufügen, erzwingen Sie, dass alle Projekte, die Ihre Bibliothek verwenden, erneut kompiliert werden. Allerdings muss keiner der Quellcodes in diesen Projekten geändert werden. Daher sind die Auswirkungen des Breaking Change auf jedes Projekt relativ gering.

Wenn Sie einen Breaking Change der Quelle an Ihrer Bibliothek vornehmen, müssen alle Projekte Quelländerungen vornehmen, um Ihre neue Bibliothek zu verwenden. Wenn die erforderliche Änderung neue Sprachfeatures erfordert, erzwingen Sie für diese Projekte das Upgrade auf dieselbe Sprachversion und den TFM, den Sie jetzt verwenden. Sie haben Ihren Benutzer*innen mehr Arbeit abverlangt und möglicherweise ein Upgrade erzwungen.

Die Auswirkungen von Breaking Changes, die Sie vornehmen, hängt von der Anzahl der Projekte ab, die eine Abhängigkeit von Ihrer Bibliothek aufweisen. Wenn Ihre Bibliothek intern von wenigen Anwendungen verwendet wird, können Sie auf Breaking Changes in allen betroffenen Projekten reagieren. Wenn Ihre Bibliothek jedoch öffentlich heruntergeladen wird, sollten Sie die potenziellen Auswirkungen bewerten und Alternativen in Betracht ziehen:

  • Sie können neue APIs hinzufügen, die parallel zu vorhandenen APIs ausgeführt werden.
  • Sie können parallele Builds für verschiedene TFMs in Betracht nutzen.
  • Sie können mehrere Zielgruppen verwenden.