Was ist CLS (Common Language Specification)?
Um unabhängig von der Sprache der Implementierung vollständig mit anderen Objekten interagieren zu können, ist es erforderlich, dass Objekte dem Aufrufer nur die Features offen legen, die allen Sprachen gemeinsam sind, mit denen sie interoperieren müssen. Deshalb wurde die CLS (Common Language Specification) definiert, ein Satz von grundlegenden Sprachfeatures, die für viele Anwendungen benötigt werden. Die CLS-Regeln definieren eine Teilmenge des allgemeinen Typensystems. Dies bedeutet, dass alle auf das allgemeine Typensystem angewendeten Regeln in CLS übernommen werden, wenn in CLS keine strengeren Regeln definiert sind. CLS verbessert und sichert die Sprachinteroperabilität durch Definieren einer Gruppe von Features, die für Entwickler in einer Vielzahl von Sprachen stets verfügbar sind. CLS bestimmt außerdem die Anforderungen bezüglich der CLS-Kompatibilität. Mit deren Hilfe können Sie ermitteln, ob der verwaltete Code der CLS entspricht und inwiefern ein bestimmtes Tool die Entwicklung von verwaltetem Code unterstützt, der CLS-Features verwendet.
Wenn die Komponente nur CLS-Features in der API verwendet, die sie anderem Code (einschließlich abgeleiteten Klassen) offen legt, wird der Zugriff auf die Komponente von allen Programmiersprachen aus garantiert, die CLS unterstützen. Komponenten, die die CLS-Regeln befolgen und nur die Features verwenden, die in der CLS enthalten sind, werden CLS-kompatible Komponenten genannt.
Die meisten Member, die von den Typen der .NET Framework-Klassenbibliothek definiert werden, sind CLS-kompatibel. Manche Typen in der Klassenbibliothek besitzen jedoch ein oder mehrere Member, die nicht CLS-kompatibel sind. Diese Member ermöglichen die Unterstützung für Sprachfeatures, die nicht in CLS enthalten sind. Die Typen und Member, die nicht CLS-kompatibel sind, werden als solche in der Referenzdokumentation gekennzeichnet, und in allen Fällen ist eine CLS-kompatible Alternative verfügbar. Weitere Informationen über die Typen in der .NET Framework-Klassenbibliothek finden Sie in der .NET Framework-Referenz.
Die CLS wurde in einer Größe entwickelt, die für die von Entwicklern i. d. R. benötigten Sprachkonstrukte ausreichend ist, und sie ist trotzdem nicht so umfangreich, dass sie von den meisten Sprachen nicht unterstützt werden könnte. Zusätzlich wurden alle Sprachkonstrukte aus CLS ausgeschlossen, die ein schnelles Überprüfen der Typsicherheit von Code verhindern. Hierdurch können alle CLS-kompatiblen Sprachen überprüfbaren Code erstellen, sofern dies erwünscht ist. Weitere Informationen über die Überprüfung der Typsicherheit finden Sie unter JIT-Kompilierung.
In der folgenden Tabelle werden die in CLS enthaltenen Features zusammengefasst, und es wird angegeben, ob die Features für Entwickler und Compiler (Alle) oder nur für Compiler gelten. Die Tabelle dient nur der Information und ist nicht vollständig. Weitere Informationen finden Sie in der Spezifikation für die Common Language Infrastructure, Partition I, die sich im Verzeichnis Tool Developers Guide befindet, das mit Microsoft .NET Framework SDK installiert wurde.
Feature | Betrifft | Beschreibung |
---|---|---|
Allgemein | ||
Sichtbarkeit |
Alle | CLS-Regeln betreffen nur die Teile eines Typs, die außerhalb der definierenden Assembly offen gelegt werden. |
Globale Member |
Alle | Globale static-Felder und Methoden sind nicht CLS-kompatibel. |
Benennung | ||
Zeichen und Groß- und Kleinschreibung |
Alle | CLS-kompatible Sprachcompiler müssen die Regeln befolgen, die in Annex 7 des Technical Report 15 für den Unicode Standard 3.0 festgelegt sind. Dort ist die Menge der Zeichen angegeben, die am Anfang von Bezeichnern stehen und in diesen enthalten sein können. Angaben zu diesem Standard finden Sie unter www.unicode.org/unicode/reports/tr15/tr15-18.html.
Zwei Bezeichner werden nicht bereits dann als unterschiedlich betrachtet wenn sie sich in Groß- und Kleinschreibung unterscheiden. |
Schlüsselwörter |
Compiler | CLS-kompatible Sprachcompiler stellen einen Mechanismus zum Verweisen auf Bezeichner bereit, die mit Schlüsselwörtern übereinstimmen. CLS-kompatible Sprachcompiler verfügen über einen Mechanismus zum Definieren und Überschreiben von Methoden mit Namen, die in der Sprache Schlüsselwörter darstellen. |
Eindeutigkeit |
Alle | Alle Namen innerhalb eines CLS-kompatiblen Gültigkeitsbereichs müssen eindeutig sein, auch wenn diese die Namen für zwei verschiedene Arten von Membern sind, es sei denn, die Namen sind identisch und werden durch Überladung aufgelöst. Beispielsweise ist es bei CLS nicht möglich, dass ein einzelner Typ denselben Namen für eine Methode und ein Feld verwendet. |
Signaturen |
Alle | Alle Rückgabe- und Parametertypen in einer Typ- oder Membersignatur müssen CLS-kompatibel sein. |
Typen | ||
Primitive Typen |
Alle | Die .NET Framework-Klassenbibliothek beinhaltet Typen, die den von Compilern verwendeten primitiven Datentypen entsprechen. Folgende Typen sind dabei CLS-kompatibel: Byte, Int16, Int32, Int64, Single, Double, Boolean, Char, Decimal, IntPtr und String. Weitere Informationen über diese Typen finden Sie unter .NET Framework-Klassenbibliothek. |
Geschachtelte Typen |
Alle | Geschachtelte Werttypen (Werttypen die in Objekte konvertiert wurden) sind nicht Teil von CLS. Verwenden Sie stattdessen entweder System.Object, System.ValueType oder System.Enum. |
Sichtbarkeit |
Alle | Typ- und Memberdeklarationen dürfen keine Typen enthalten, die weniger sichtbar oder zugänglich sind als der deklarierte Typ oder Member. |
Schnittstellenmethoden |
Compiler | CLS-kompatible Sprachcompiler benötigen eine Syntax für den Fall, dass ein einzelner Typ zwei Schnittstellen implementiert. Außerdem muss für jede dieser Schnittstellen eine Methode mit demselben Namen und derselben Signatur definiert sein. Diese Methoden müssen als unterschiedlich betrachtet werden und verlangen nicht dieselbe Implementierung. |
Abgeschlossenheit |
Alle | Die einzelnen Member CLS-kompatibler Schnittstellen und abstrakter Klassen müssen CLS-kompatibel definiert sein. |
Konstruktoraufruf |
Alle | Bevor der Konstruktor auf geerbte Instanzdaten zugreift, muss dieser den Konstruktor der Basisklasse aufrufen. |
Typisierte Verweise |
Alle | Typisierte Verweise sind nicht CLS-kompatibel. (Ein typisierter Verweis ist ein spezielles Konstrukt, das einen Verweis auf ein Objekt und einen Verweis auf einen Typ enthält. Typisierte Verweise ermöglichen es, dass die Common Language Runtime eine C++-ähnliche Unterstützung für Methoden bereitstellt, die über eine variable Anzahl von Argumenten verfügen.) |
Typmember | ||
Überladen |
Alle | Indizierte Eigenschaften, Methoden und Konstruktoren dürfen überladen werden, Felder und Ereignisse jedoch nicht.
Eigenschaften dürfen nicht nach Typ (d. h. nach dem Rückgabetyp der Get-Methode) überladen werden; sie können jedoch mit einer unterschiedlichen Anzahl oder einem unterschiedlichen Typ von Indizes überladen werden. Bei Methoden ist eine Überladung nur bezüglich der Anzahl und der Typen der Parameter zulässig. Das Überladen des Operators ist nicht in CLS enthalten. CLS stellt jedoch Richtlinien über die Angabe geeigneter Namen (z. B. Add()) und das Festlegen von Bits in den Metadaten bereit. Compiler, die das Überladen von Operatoren unterstützen, sollten diese Richtlinien befolgen. Dies ist jedoch nicht zwingend erforderlich. |
Eindeutigkeit überladener Member |
Alle | Felder und geschachtelte Typen müssen sich lediglich durch Vergleich der Bezeichner unterscheiden lassen. Methoden, Eigenschaften und Ereignisse mit demselben Namen (nach Bezeichnervergleich) müssen sich durch mehr als nur den Rückgabetyp unterscheiden. |
Konvertierungsoperatoren |
Alle | Wenn der Rückgabetyp von op_Implicit oder op_Explicit überladen ist, muss eine alternative Möglichkeit für die Konvertierung bereitgestellt werden. |
Methoden | ||
Zugriff auf überschriebene Methoden |
Alle | Beim Überschreiben von geerbten Methoden darf der Zugriff nicht geändert werden, außer wenn eine Methode überschrieben wird, die von einer anderen Assembly mit FamilyOrAssembly-Zugriff vererbt wurde. In diesem Fall muss für die Überschreibung Family-Zugriff festgelegt werden. |
Argumentlisten |
Alle | Die einzige von der CLS unterstützte Aufrufkonvention ist die verwaltete Standardaufrufkonvention. Argumentlisten mit variabler Länge sind nicht zulässig. (Für die Unterstützung einer variablen Anzahl von Argumenten verwenden Sie in Microsoft Visual Basic das Schlüsselwort ParamArray und in C# das Schlüsselwort params.) |
Eigenschaften | ||
Accessormetadaten |
Compiler | Die Get-Methode und die Set-Methode, die die Methoden einer Eigenschaft implementieren, sind in den Metadaten mit dem Bezeichner mdSpecialName markiert. |
Accessorzugriff |
Alle | Der Zugriff auf die Eigenschaft muss mit dem Zugriff auf die Accessoren identisch sein. |
Modifizierer |
Alle | Die Eigenschaft und die Accessoren müssen alle static, alle virtual oder alle instance sein. |
Accessornamen |
Alle | Eigenschaften müssen einem bestimmten Benennungsschema folgen. Für eine Eigenschaft mit dem Namen Name erhält die Get-Methode, sofern definiert, den Namen get_Name und die Set-Methode, sofern definiert, den Namen set_Name. |
Rückgabetyp und Argumente |
Alle | Der Typ der Eigenschaft entspricht dem Rückgabetyp der Get-Methode und dem Typ des letzten Arguments der Set-Methode. Die Parametertypen der Eigenschaft entsprechen den Parametertypen der Get-Methode und, ausgenommen dem letzten, allen Parametertypen der Set-Methode. Diese Typen müssen CLS-kompatibel sein und dürfen keine verwalteten Zeiger sein. Sie dürfen nicht als Verweise übergeben werden. |
Ereignisse | ||
Ereignismethoden |
Alle | Die Methoden für das Hinzufügen oder Entfernen eines Ereignisses müssen entweder beide vorhanden oder beide nicht vorhanden sein. |
Metadaten für Ereignismethoden |
Compiler | Methoden, mit denen ein Ereignis implementiert wird, müssen in den Metadaten mit dem Bezeichner mdSpecialName markiert sein. |
Accessorzugriff |
Alle | Der Zugriff auf die Methoden für das Hinzufügen, Entfernen und Auslösen eines Ereignisses muss identisch sein. |
Modifizierer |
Alle | Die Methoden für das Hinzufügen, Entfernen oder Auslösen eines Ereignisses müssen entweder alle static, alle virtual oder alle instance sein. |
Ereignismethodennamen |
Alle | Ereignisse müssen einem bestimmten Benennungsschema folgen. Für ein Ereignis mit dem Namen MyEvent erhält die Add-Methode, sofern definiert, den Namen add_MyEvent, die Remove-Methode, sofern definiert, erhält den Namen remove_MyEvent, und die Raise-Methode erhält den Namen raise_MyEvent. |
Argumente |
Alle | Die Methoden für das Hinzufügen und Entfernen eines Ereignisses müssen jeweils einen Parameter erhalten, dessen Typ den Ereignistyp definiert, und dieser Typ muss von System.Delegate abgeleitet sein. |
Zeigertypen | ||
Zeiger |
Alle | Zeigertypen und Funktionszeigertypen sind nicht CLS-kompatibel. |
Schnittstellen | ||
Membersignaturen |
Alle | Zum Implementieren von CLS-kompatiblen Schnittstellen darf keine Definition von nicht CLS-kompatiblen Methoden erforderlich sein. |
Membermodifizierer |
Alle | CLS-kompatible Schnittstellen können weder statische Methoden noch Felder definieren. Sie können Eigenschaften, Ereignisse und virtuelle Methoden definieren. |
Verweistypen | ||
Konstruktoraufruf |
Alle | Bei Verweistypen werden Objektkonstruktoren nur im Rahmen der Objekterstellung aufgerufen, und Objekte werden nur einmal initialisiert. |
Klassentypen | ||
Vererbung |
Alle | Eine CLS-kompatible Klasse muss von einer ebenfalls CLS-kompatiblen Klasse erben. (System.Object ist CLS-kompatibel.) |
Arrays | ||
Elementtypen |
Alle | Arrayelemente müssen CLS-kompatible Typen sein. |
Dimensionen |
Alle | Für Arrays ist eine festgelegte Anzahl von Dimensionen größer als null erforderlich. |
Begrenzungen |
Alle | Die unteren Begrenzungen aller Dimensionen eines Arrays müssen gleich 0 sein. |
Enumerationen | ||
Zugrunde liegender Typ |
Alle | Der zugrunde liegende Typ einer Enumeration muss ein integrierter CLS-Ganzzahltyp sein (Byte, Int16, Int32 oder Int64). |
FlagsAttribute |
Compiler | Das Vorhandensein des benutzerdefinierten System.FlagsAttribute-Attributs in der Definition einer Enumeration gibt an, dass die Enumeration als Satz von Bitfeldern (Flags) behandelt werden muss. Wenn dieses Attribut nicht vorhanden ist, wird der Typ als Gruppe von Enumerationskonstanten betrachtet. Es wird empfohlen, dass Sprachen entweder das FlagsAttribute oder eine sprachspezifische Syntax verwenden, um zwischen diesen beiden Enumerationstypen zu unterscheiden. |
Feldmember |
Alle | Literale static-Felder einer Enumeration müssen vom gleichen Typ sein wie die Enumeration selbst. |
Ausnahmen | ||
Vererbung |
Alle | Auszulösende Objekte müssen vom Typ System.Exception sein oder von System.Exception erben. |
Benutzerdefinierte Attribute | ||
Codierung von Werten |
Compiler | Mit CLS kompatible Compiler müssen nur eine Teilmenge der Codierungen von benutzerdefinierten Attributen behandeln (d. h. die Darstellung benutzerdefinierter Attribute in den Metadaten). Die einzigen zulässigen Typen in diesen Codierungen sind: System.Type, System.String, System.Char, System.Boolean, System.Byte, System.Int16, System.Int32, System.Int64, System.Single, System.Double sowie alle Enumerationstypen, die auf einem mit CLS kompatiblen Basisganzzahltyp basieren. |
Metadaten | ||
CLS-Kompatibilität |
Alle | Typen, deren CLS-Kompatibilität von der der Assembly abweicht, in der sie definiert sind, müssen entsprechend mit dem System.CLSCompliantAttribute markiert werden. Ebenso müssen Member markiert werden, deren CLS-Kompatibilität sich von der des Typs unterscheidet. Wenn ein Member oder ein Typ als nicht CLS-kompatibel markiert ist, muss eine CLS-kompatible Alternative bereitgestellt werden. |
Siehe auch
Sprachübergreifende Interoperabilität | Übersicht über die Sprachinteroperabilität