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.
(Bild: Alex SG/Shutterstock.com)
- 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.
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.
Videos by heise
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.
Beispiel fĂĽr den Einsatz
Als Beispiel dient Code, der den Inhalt einer Datei zeigt, die drei Typen deklariert:
- Schnittstelle
IPersonmit Scopepublic - Klasse
Person, dieIPersonimplementiert, mit Scopefile - Klasse
PersonManagermit Scopepublic
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)