Neu in .NET 7 [4]: Zusätzlicher Scope mit File-local Types in C# 11

Das aktuelle Release von Microsofts Programmiersprache C# führt mit file einen neuen Scope für Klassen, Strukturen, Interfaces und Co ein.

Lesezeit: 2 Min.
In Pocket speichern
vorlesen Druckansicht Kommentare lesen 8 Beiträge
Female,Hand,Holds,Black,Binoculars,On,A,Yellow,Background.,Journey,

(Bild: Alex SG/Shutterstock.com)

Von
  • Dr. Holger Schwichtenberg

C# 11 führt für .NET-Typen die Sichtbarkeit (Scope) file zusätzlich zu den bisher bekannten public, private, protected, internal, protected internal und private protected ein.

Der Dotnet-Doktor – Holger Schwichtenberg

Dr. Holger Schwichtenberg ist Chief Technology Expert bei MAXIMAGO, die Innovations- und Experience-getriebener Softwareentwicklung, u.a. in hochkritischen sicherheitstechnischen Bereichen, anbietet. Zudem ist er Leiter des Expertennetzwerks www.IT-Visions.de, das mit 38 renommierten Experten zahlreiche mittlere und große Unternehmen durch Beratung und Schulung bei der Entwicklung sowie dem Betrieb von Software unterstützt.

Mit dem neuen Schlüsselwort file versehene Schnittstellen, Klassen, Strukturen, Enumerationen, Delegates und Records sind nur innerhalb der Datei sichtbar, in der sie deklariert werden. Für eingebettete Typen ist file nicht erlaubt.

Auf den ersten Blick widerspricht die Sichtbarkeit file den von Microsoft seit Jahren gepredigten Best Practices, pro Datei nur einen einzigen Typ zu deklarieren. Wenn man diesen einen Typ dann mit dem Zusatz file ausstattet, ist er außerhalb der Datei nicht sichtbar und damit überflüssig.

In der Praxis kann es aber durchaus sinnvoll sein, mehrere kleinere Typen in einer Datei zu deklarieren, etwa weil eine Klasse eine eigene persönliche, nur für diese Klasse geltende Datenstruktur in Form einer anderen Klasse oder eines Record-Typs erhält. Microsoft hat den Scope file für die Source Generators eingeführt: Sie sollen Hilfsklassen erzeugen können, ohne in Konflikt mit anderen Generatoren zu geraten.

Als Beispiel dient Code, der den Inhalt einer Datei zeigt, die drei Typen deklariert:

  • Schnittstelle IPerson mit Scope public
  • Klasse Person, die IPerson implementiert, mit Scope file
  • Klasse PersonManager mit Scope public

Der Code zeigt: PersonManager kann durchaus eine Instanz von Person an die Außenwelt (Code in anderen Dateien) liefern, denn diese können die Instanz über Schnittstelle IPerson verwenden. Die Außenwelt kann aber keine Instanz von Person hineinreichen, weil sie diese Klasse nicht kennt.

namespace NET7Console;
 
public interface IPerson
{
 public int ID { get; set; }
 public string? Name { get; set; }
 public string GetInfo();
}
 
file class Person : IPerson
{
 public int ID { get; set; }
 public string? Name { get; set; }
 public string GetInfo() => 
   $"{this.GetType().FullName} {this.ID}: {this.Name}";
}
 
public class PersonManager 
{
 public int ID { get; set; }
 public string? Name { get; set; }
 
 public string GetInfoFromTestPerson()
 {
  Person p = new();
  return p.GetInfo();
 }
 
 public IPerson CreatePerson() 
 {
  return new Person();
 }
 
 // Nicht möglich: File-local type 'Person' cannot be used 
 // in a member signature in non-file-local type 'PersonManager'.	
 //public int GetInfo(Person p) 
 //{
 // return p.GetInfo();
 //}
}

Typen mit file-Scope bekommen einen vom Compiler vergebenen Namenszusatz, der sie eindeutig macht. Der Namensaufbau ist: <Dateiname>HEX-ZAHL__Typname.

Ein Typ mit Scope file kann einen anderen Typen, der übergeordnet sichtbar ist, verdecken. Beispiel: Wenn es neben einer Klasse Person in der Datei Person.cs, die internal oder public ist, noch einen Klasse file class Person in Test.cs gibt, ist innerhalb dieser Datei Test.cs der Typ Person aus Person.cs nicht sichtbar.

(rme)