Grundlegende KonzepteBasic concepts

AnwendungsstartApplication Startup

Eine Assembly mit dem -**Einstiegspunkt* _ wird als Anwendung bezeichnet.An assembly that has an entry point _ is called an _application*_. Wenn eine Anwendung ausgeführt wird, wird eine neue _-Anwendungsdomäne* erstellt.When an application is run, a new _ application domain* is created. Mehrere verschiedene Instanziierungen einer Anwendung können gleichzeitig auf demselben Computer vorhanden sein, und jede verfügt über eine eigene Anwendungsdomäne.Several different instantiations of an application may exist on the same machine at the same time, and each has its own application domain.

Eine Anwendungsdomäne ermöglicht die Anwendungs Isolation, indem Sie als Container für den Anwendungs Zustand fungiert.An application domain enables application isolation by acting as a container for application state. Eine Anwendungsdomäne fungiert als Container und Grenze für die Typen, die in der Anwendung definiert sind, und die Klassenbibliotheken, die Sie verwendet.An application domain acts as a container and boundary for the types defined in the application and the class libraries it uses. Typen, die in eine Anwendungsdomäne geladen werden, unterscheiden sich vom gleichen Typ, der in eine andere Anwendungsdomäne geladen wurde, und Instanzen von Objekten werden nicht direkt zwischen Anwendungs Domänen freigegeben.Types loaded into one application domain are distinct from the same type loaded into another application domain, and instances of objects are not directly shared between application domains. Zum Beispiel verfügt jede Anwendungsdomäne über eine eigene Kopie statischer Variablen für diese Typen, und ein statischer Konstruktor für einen Typ wird höchstens einmal pro Anwendungsdomäne ausgeführt.For instance, each application domain has its own copy of static variables for these types, and a static constructor for a type is run at most once per application domain. Implementierungen können mit Implementierungs spezifischen Richtlinien oder Mechanismen für die Erstellung und Zerstörung von Anwendungs Domänen bereitgestellt werden.Implementations are free to provide implementation-specific policy or mechanisms for the creation and destruction of application domains.

Der Anwendungsstart erfolgt, wenn die Ausführungsumgebung eine bestimmte Methode aufruft, die als Einstiegspunkt der Anwendung bezeichnet wird.Application startup occurs when the execution environment calls a designated method, which is referred to as the application's entry point. Diese Einstiegspunkt Methode Main hat immer den Namen und kann eine der folgenden Signaturen aufweisen:This entry point method is always named Main, and can have one of the following signatures:

static void Main() {...}

static void Main(string[] args) {...}

static int Main() {...}

static int Main(string[] args) {...}

Wie gezeigt, kann der Einstiegspunkt optional einen- int Wert zurückgeben.As shown, the entry point may optionally return an int value. Dieser Rückgabewert wird beim Beenden der Anwendung (Beendigung der Anwendung) verwendet.This return value is used in application termination (Application termination).

Der Einstiegspunkt kann optional einen formalen Parameter aufweisen.The entry point may optionally have one formal parameter. Der-Parameter kann einen beliebigen Namen haben, aber der Typ des-Parameters muss lauten string[] .The parameter may have any name, but the type of the parameter must be string[]. Wenn der formale Parameter vorhanden ist, erstellt und übergibt die Ausführungsumgebung ein-Argument, das string[] die Befehlszeilenargumente enthält, die beim Starten der Anwendung angegeben wurden.If the formal parameter is present, the execution environment creates and passes a string[] argument containing the command-line arguments that were specified when the application was started. Das string[] Argument ist nie NULL, kann jedoch eine Länge von 0 (null) aufweisen, wenn keine Befehlszeilenargumente angegeben wurden.The string[] argument is never null, but it may have a length of zero if no command-line arguments were specified.

Da c# das Überladen von Methoden unterstützt, kann eine Klasse oder Struktur mehrere Definitionen einer Methode enthalten, vorausgesetzt, jede hat eine andere Signatur.Since C# supports method overloading, a class or struct may contain multiple definitions of some method, provided each has a different signature. Allerdings kann in einem einzelnen Programm keine Klasse oder Struktur mehr als eine Methode mit dem Namen enthalten, Main deren Definition die Verwendung als Anwendungs Einstiegspunkt qualifiziert.However, within a single program, no class or struct may contain more than one method called Main whose definition qualifies it to be used as an application entry point. Andere überladene Versionen von Main sind jedoch zulässig, vorausgesetzt, Sie verfügen über mehr als einen Parameter, oder der einzige Parameter ist ein anderer Parameter als Type string[] .Other overloaded versions of Main are permitted, however, provided they have more than one parameter, or their only parameter is other than type string[].

Eine Anwendung kann aus mehreren Klassen oder Strukturen bestehen.An application can be made up of multiple classes or structs. Es ist möglich, dass mehr als eine dieser Klassen oder Strukturen eine Methode mit dem Namen enthält, Main deren Definition die Verwendung als Anwendungs Einstiegspunkt qualifiziert.It is possible for more than one of these classes or structs to contain a method called Main whose definition qualifies it to be used as an application entry point. In solchen Fällen muss ein externer Mechanismus (z. b. eine Befehlszeilen-Compileroption) verwendet werden, um eine dieser Main Methoden als Einstiegspunkt auszuwählen.In such cases, an external mechanism (such as a command-line compiler option) must be used to select one of these Main methods as the entry point.

In c# muss jede Methode als Member einer Klasse oder Struktur definiert werden.In C#, every method must be defined as a member of a class or struct. Normalerweise wird die deklarierte Barrierefreiheit (derdeklarierteZugriff) einer Methode durch die Zugriffsmodifizierer (Zugriffsmodifizierer) bestimmt, die in der Deklaration angegeben sindOrdinarily, the declared accessibility (Declared accessibility) of a method is determined by the access modifiers (Access modifiers) specified in its declaration, and similarly the declared accessibility of a type is determined by the access modifiers specified in its declaration. Damit eine bestimmte Methode eines bestimmten Typs aufgerufen werden kann, muss der Zugriff auf den Typ und den Member möglich sein.In order for a given method of a given type to be callable, both the type and the member must be accessible. Der Einstiegspunkt der Anwendung ist jedoch ein Sonderfall.However, the application entry point is a special case. Insbesondere kann die Ausführungsumgebung auf den Einstiegspunkt der Anwendung zugreifen, unabhängig von der deklarierten Barrierefreiheit und unabhängig von der deklarierten Barrierefreiheit ihrer einschließenden Typdeklarationen.Specifically, the execution environment can access the application's entry point regardless of its declared accessibility and regardless of the declared accessibility of its enclosing type declarations.

Die Einstiegspunkt Methode der Anwendung darf sich nicht in einer generischen Klassen Deklaration befinden.The application entry point method may not be in a generic class declaration.

In allen anderen Punkten verhalten sich Einstiegspunkt Methoden wie solche, die keine Einstiegspunkte sind.In all other respects, entry point methods behave like those that are not entry points.

Application termination (Beenden von Anwendungen)Application termination

Beim Beenden der Anwendung wird die Steuerung an die Ausführungsumgebung zurückgegeben.Application termination returns control to the execution environment.

Wenn der Rückgabetyp der *Entry Point _-Methode der Anwendung ist int , wird der zurückgegebene Wert als _ -Beendigungs Statuscode * der Anwendung dienen.If the return type of the application's entry point _ method is int, the value returned serves as the application's _termination status code**. Der Zweck dieses Codes besteht darin, die Kommunikation über Erfolg oder Misserfolg der Ausführungsumgebung zuzulassen.The purpose of this code is to allow communication of success or failure to the execution environment.

Wenn der Rückgabetyp der Einstiegspunkt Methode ist void und die Rechte geschweifter Klammer () erreicht wird, } die diese Methode beendet oder eine Anweisung ausführt, return die keinen Ausdruck hat, führt dies zu einem Beendigungs Statuscode von 0 .If the return type of the entry point method is void, reaching the right brace (}) which terminates that method, or executing a return statement that has no expression, results in a termination status code of 0.

Vor dem Beenden einer Anwendung werden Dekonstruktoren für alle Objekte, die noch keine Garbage Collection durchgeführt haben, aufgerufen, es sei denn, eine solche Bereinigung wurde unterdrückt (z. b. durch einen Aufruf der Library-Methode GC.SuppressFinalize ).Prior to an application's termination, destructors for all of its objects that have not yet been garbage collected are called, unless such cleanup has been suppressed (by a call to the library method GC.SuppressFinalize, for example).

DeklarationenDeclarations

Deklarationen in einem c#-Programm definieren die Bestandteile des Programms.Declarations in a C# program define the constituent elements of the program. C#-Programme werden mithilfe von Namespaces (Namespaces) organisiert, die Typdeklarationen und schsted Namespace Deklarationen enthalten können.C# programs are organized using namespaces (Namespaces), which can contain type declarations and nested namespace declarations. Typdeklarationen (Typdeklarationen) werden verwendet, um Klassen (Klassen), Strukturen (Strukturen), Schnittstellen (Schnittstellen), Enumerationen (Enumerationen) und Delegaten (Delegaten) zu definieren.Type declarations (Type declarations) are used to define classes (Classes), structs (Structs), interfaces (Interfaces), enums (Enums), and delegates (Delegates). Die Arten von Membern, die in einer Typdeklaration zulässig sind, hängen von der Form der Typdeklaration ab.The kinds of members permitted in a type declaration depend on the form of the type declaration. Klassen Deklarationen können z. a. Deklarationen für Konstanten (Konstanten) enthalten, Felder (Felder), Methoden (Methoden), Eigenschaften (Eigenschaften), Ereignisse (Ereignisse), Indexer (Indexer), Operatoren (Operatoren), Instanzkonstruktoren (Instanzkonstruktoren), statische Konstruktoren (statische Konstruktoren), Dekonstruktoren (debugtoren) und geclusterte Typen (geclusterte Typen).For instance, class declarations can contain declarations for constants (Constants), fields (Fields), methods (Methods), properties (Properties), events (Events), indexers (Indexers), operators (Operators), instance constructors (Instance constructors), static constructors (Static constructors), destructors (Destructors), and nested types (Nested types).

Eine Deklaration definiert einen Namen im Deklarations Bereich , zu dem die Deklaration gehört.A declaration defines a name in the declaration space to which the declaration belongs. Mit Ausnahme überladener Elemente (Signaturen und überladen) handelt es sich um einen Kompilierzeitfehler, der zwei oder mehr Deklarationen mit demselben Namen in einem Deklarations Raum einführt.Except for overloaded members (Signatures and overloading), it is a compile-time error to have two or more declarations that introduce members with the same name in a declaration space. Es ist nie möglich, dass ein Deklarations Bereich unterschiedliche Arten von Membern mit dem gleichen Namen enthält.It is never possible for a declaration space to contain different kinds of members with the same name. Beispielsweise kann ein Deklarations Raum nie ein Feld und eine Methode mit demselben Namen enthalten.For example, a declaration space can never contain a field and a method by the same name.

Es gibt mehrere verschiedene Typen von Deklarations Bereichen, die im folgenden beschrieben werden.There are several different types of declaration spaces, as described in the following.

  • Innerhalb aller Quelldateien eines Programms sind namespace_member_declaration s ohne einschließende namespace_declaration Member eines einzelnen kombinierten Deklarations Raums, der als globaler Deklarations Bereich bezeichnet wird.Within all source files of a program, namespace_member_declaration s with no enclosing namespace_declaration are members of a single combined declaration space called the global declaration space.
  • Innerhalb aller Quelldateien eines Programms sind namespace_member_declaration s innerhalb namespace_declaration en, die denselben voll qualifizierten Namespace Namen aufweisen, Mitglieder eines einzelnen kombinierten Deklarations Raums.Within all source files of a program, namespace_member_declaration s within namespace_declaration s that have the same fully qualified namespace name are members of a single combined declaration space.
  • Jede Klassen-, Struktur-oder Schnittstellen Deklaration erstellt einen neuen Deklarations Bereich.Each class, struct, or interface declaration creates a new declaration space. Namen werden in diesem Deklarations Bereich durch class_member_declaration s, struct_member_declaration s, interface_member_declaration s oder type_parameter s eingeführt.Names are introduced into this declaration space through class_member_declaration s, struct_member_declaration s, interface_member_declaration s, or type_parameter s. Mit Ausnahme von überladenen Instanzkonstruktordeklarationen und statischen Konstruktordeklarationen kann eine Klasse oder Struktur keine Element Deklaration mit dem gleichen Namen wie die Klasse oder Struktur enthalten.Except for overloaded instance constructor declarations and static constructor declarations, a class or struct cannot contain a member declaration with the same name as the class or struct. Eine Klasse, Struktur oder Schnittstelle ermöglicht die Deklaration überladener Methoden und Indexer.A class, struct, or interface permits the declaration of overloaded methods and indexers. Außerdem ermöglicht eine Klasse oder Struktur die Deklaration überladener Instanzkonstruktoren und Operatoren.Furthermore, a class or struct permits the declaration of overloaded instance constructors and operators. Eine Klasse, Struktur oder Schnittstelle kann z. b. mehrere Methoden Deklarationen mit demselben Namen enthalten, sofern sich diese Methoden Deklarationen in Ihrer Signatur (Signaturen und überladen) unterscheiden.For example, a class, struct, or interface may contain multiple method declarations with the same name, provided these method declarations differ in their signature (Signatures and overloading). Beachten Sie, dass Basisklassen nicht zum Deklarations Bereich einer Klasse beitragen und Basis Schnittstellen nicht zum Deklarations Bereich einer Schnittstelle beitragen.Note that base classes do not contribute to the declaration space of a class, and base interfaces do not contribute to the declaration space of an interface. Daher kann eine abgeleitete Klasse oder Schnittstelle einen Member mit demselben Namen wie ein geerbten Member deklarieren.Thus, a derived class or interface is allowed to declare a member with the same name as an inherited member. Ein solcher Member gibt an, dass der geerbte Member ausgeblendet wird.Such a member is said to hide the inherited member.
  • Jede Delegatdeklaration erstellt einen neuen Deklarations Bereich.Each delegate declaration creates a new declaration space. Namen werden in diesem Deklarations Raum durch formale Parameter (fixed_parameter s und parameter_array s) und type_parameter s eingeführt.Names are introduced into this declaration space through formal parameters (fixed_parameter s and parameter_array s) and type_parameter s.
  • Jede Enumerationsdeklaration erstellt einen neuen Deklarations Bereich.Each enumeration declaration creates a new declaration space. Namen werden in diesem Deklarations Raum durch enum_member_declarations eingeführt.Names are introduced into this declaration space through enum_member_declarations.
  • Jede Methoden Deklaration, Indexer-Deklaration, Operator Deklaration, Instanzkonstruktordeklaration und anonyme Funktion erstellt einen neuen Deklarations Bereich, der als *lokaler Variablen Deklarations Raum _ bezeichnet wird.Each method declaration, indexer declaration, operator declaration, instance constructor declaration and anonymous function creates a new declaration space called a *local variable declaration space _. Namen werden in diesem Deklarations Raum durch formale Parameter (_fixed_parameter * s und parameter_array s) und type_parameter s eingeführt.Names are introduced into this declaration space through formal parameters (_fixed_parameter*s and parameter_array s) and type_parameter s. Der Text des Funktionsmembers oder der anonymen Funktion wird, falls vorhanden, als geschachtelt im lokalen Variablen Deklarations Bereich betrachtet.The body of the function member or anonymous function, if any, is considered to be nested within the local variable declaration space. Es ist ein Fehler bei einem Deklarations Raum für lokale Variablen und einem in der Tabelle enthaltenen Deklarations Bereich der lokalen Variablen, der Elemente mit dem gleichen Namen enthalten soll.It is an error for a local variable declaration space and a nested local variable declaration space to contain elements with the same name. Daher ist es in einem geschachtelten Deklarations Bereich nicht möglich, eine lokale Variable oder Konstante mit dem gleichen Namen wie eine lokale Variable oder Konstante in einem einschließenden Deklarations Bereich zu deklarieren.Thus, within a nested declaration space it is not possible to declare a local variable or constant with the same name as a local variable or constant in an enclosing declaration space. Es ist möglich, dass zwei Deklarations Bereiche Elemente mit dem gleichen Namen enthalten, solange kein Deklarations Raum den anderen enthält.It is possible for two declaration spaces to contain elements with the same name as long as neither declaration space contains the other.
  • Jeder Block oder switch_block sowie eine for-, foreach -und using -Anweisung erstellt einen lokalen Variablen Deklarations Raum für lokale Variablen und lokale Konstanten.Each block or switch_block , as well as a for, foreach and using statement, creates a local variable declaration space for local variables and local constants . Namen werden in diesem Deklarations Raum durch local_variable_declaration s und local_constant_declaration s eingeführt.Names are introduced into this declaration space through local_variable_declaration s and local_constant_declaration s. Beachten Sie, dass Blöcke, die als oder innerhalb des Texts eines Funktionsmembers oder einer anonymen Funktion auftreten, innerhalb des Deklarations Raums für lokale Variablen geschachtelt sind, der von diesen Funktionen für Ihre Parameter deklariert wird.Note that blocks that occur as or within the body of a function member or anonymous function are nested within the local variable declaration space declared by those functions for their parameters. Daher ist es ein Fehler, z. b. eine Methode mit einer lokalen Variablen und einem Parameter mit dem gleichen Namen zu haben.Thus it is an error to have e.g. a method with a local variable and a parameter of the same name.
  • Jeder Block oder switch_block erstellt einen separaten Deklarations Raum für Bezeichnungen.Each block or switch_block creates a separate declaration space for labels. Namen werden in diesem Deklarations Bereich durch labeled_statement s eingeführt, und auf die Namen wird über goto_statement s verwiesen.Names are introduced into this declaration space through labeled_statement s, and the names are referenced through goto_statement s. Der Zeichenbereich der Bezeichnungs Deklaration eines-Blocks enthält alle in der Liste enthaltenen Blöcke.The label declaration space of a block includes any nested blocks. Daher ist es in einem geschachtelten Block nicht möglich, eine Bezeichnung mit demselben Namen wie eine Bezeichnung in einem einschließenden Block zu deklarieren.Thus, within a nested block it is not possible to declare a label with the same name as a label in an enclosing block.

Die Text Reihenfolge, in der die Namen deklariert werden, ist im Allgemeinen nicht von Bedeutung.The textual order in which names are declared is generally of no significance. Insbesondere ist die Text Reihenfolge für die Deklaration und Verwendung von Namespaces, Konstanten, Methoden, Eigenschaften, Ereignissen, Indexern, Operatoren, Instanzkonstruktoren, Dekonstruktoren, statischen Konstruktoren und Typen nicht signifikant.In particular, textual order is not significant for the declaration and use of namespaces, constants, methods, properties, events, indexers, operators, instance constructors, destructors, static constructors, and types. Die Deklarations Reihenfolge ist wie folgt signifikant:Declaration order is significant in the following ways:

  • Die Deklarations Reihenfolge für Feld Deklarationen und lokale Variablen Deklarationen bestimmt die Reihenfolge, in der Ihre Initialisierer (sofern vorhanden) ausgeführt werden.Declaration order for field declarations and local variable declarations determines the order in which their initializers (if any) are executed.
  • Lokale Variablen müssen definiert werden, bevor Sie verwendet werden (Bereiche).Local variables must be defined before they are used (Scopes).
  • Die Deklarations Reihenfolge für Enumerationmember-Deklarationen (Enumeration-Member) ist wichtig, wenn constant_expression Werte ausgelassen werdenDeclaration order for enum member declarations (Enum members) is significant when constant_expression values are omitted.

Der Deklarations Bereich eines Namespaces ist "Open End", und zwei Namespace Deklarationen mit demselben voll qualifizierten Namen tragen zum selben Deklarations Bereich bei.The declaration space of a namespace is "open ended", and two namespace declarations with the same fully qualified name contribute to the same declaration space. Beispiel:For example

namespace Megacorp.Data
{
    class Customer
    {
        ...
    }
}

namespace Megacorp.Data
{
    class Order
    {
        ...
    }
}

Die beiden oben genannten Namespace Deklarationen tragen zum selben Deklarations Bereich bei, in diesem Fall werden zwei Klassen mit den voll qualifizierten Namen Megacorp.Data.Customer und deklariert Megacorp.Data.Order .The two namespace declarations above contribute to the same declaration space, in this case declaring two classes with the fully qualified names Megacorp.Data.Customer and Megacorp.Data.Order. Da die beiden Deklarationen zum gleichen Deklarations Bereich beitragen, hätte Sie einen Kompilierzeitfehler verursacht, wenn jeder eine Deklaration einer Klasse mit dem gleichen Namen enthielt.Because the two declarations contribute to the same declaration space, it would have caused a compile-time error if each contained a declaration of a class with the same name.

Wie oben angegeben, enthält der Deklarations Bereich eines-Blocks alle in der Liste enthaltenen Blöcke.As specified above, the declaration space of a block includes any nested blocks. Folglich führen im folgenden Beispiel die F -Methode und die- G Methode zu einem Kompilierzeitfehler, da der Name i im äußeren Block deklariert ist und nicht im Inneren Block erneut deklariert werden kann.Thus, in the following example, the F and G methods result in a compile-time error because the name i is declared in the outer block and cannot be redeclared in the inner block. Die- H Methode und die I -Methode sind jedoch gültig, da die beiden i in separaten nicht--Blöcken deklariert werden.However, the H and I methods are valid since the two i's are declared in separate non-nested blocks.

class A
{
    void F() {
        int i = 0;
        if (true) {
            int i = 1;            
        }
    }

    void G() {
        if (true) {
            int i = 0;
        }
        int i = 1;                
    }

    void H() {
        if (true) {
            int i = 0;
        }
        if (true) {
            int i = 1;
        }
    }

    void I() {
        for (int i = 0; i < 10; i++)
            H();
        for (int i = 0; i < 10; i++)
            H();
    }
}

MemberMembers

Namespaces und Typen verfügen über Mitglieder.Namespaces and types have members. Die Member einer Entität sind in der Regel über einen qualifizierten Namen verfügbar, der mit einem Verweis auf die Entität beginnt, gefolgt von einem " . "-Token, gefolgt vom Namen des Members.The members of an entity are generally available through the use of a qualified name that starts with a reference to the entity, followed by a "." token, followed by the name of the member.

Member eines Typs werden entweder in der Typdeklaration deklariert oder von der Basisklasse des Typs geerbt .Members of a type are either declared in the type declaration or inherited from the base class of the type. Wenn ein Typ von einer Basisklasse erbt, werden alle Member der Basisklasse, ausgenommen Instanzkonstruktoren, destrukturtoren und statische Konstruktoren, zu Membern des abgeleiteten Typs.When a type inherits from a base class, all members of the base class, except instance constructors, destructors and static constructors, become members of the derived type. Der deklarierte Zugriff eines Basisklassenmembers steuert nicht, ob der Member geerbt wird – die Vererbung wird auf einen Member ausgedehnt, der kein Instanzkonstruktor, statischer Konstruktor oder Dekonstruktor ist.The declared accessibility of a base class member does not control whether the member is inherited—inheritance extends to any member that isn't an instance constructor, static constructor, or destructor. Es ist jedoch möglich, dass auf einen geerbten Member nicht in einem abgeleiteten Typ zugegriffen werden kann, entweder aufgrund seiner deklarierten Barrierefreiheit (deklariert Barrierefreiheit) oder weil er durch eine Deklaration im Typ selbst ausgeblendet wird (durch Vererbung verbergen).However, an inherited member may not be accessible in a derived type, either because of its declared accessibility (Declared accessibility) or because it is hidden by a declaration in the type itself (Hiding through inheritance).

Namespace members (Namespacemember)Namespace members

Namespaces und Typen, die keinen einschließenden Namespace aufweisen, sind Member des globalen Namespace.Namespaces and types that have no enclosing namespace are members of the global namespace. Dies entspricht direkt den im globalen Deklarations Bereich deklarierten Namen.This corresponds directly to the names declared in the global declaration space.

Namespaces und Typen, die in einem Namespace deklariert werden, sind Member dieses Namespace.Namespaces and types declared within a namespace are members of that namespace. Dies entspricht direkt den Namen, die im Deklarations Raum des-Namespace deklariert werden.This corresponds directly to the names declared in the declaration space of the namespace.

Namespaces haben uneingeschränkten Zugriff.Namespaces have no access restrictions. Es ist nicht möglich, private, geschützte oder interne Namespaces zu deklarieren, und Namespace Namen sind immer öffentlich zugänglich.It is not possible to declare private, protected, or internal namespaces, and namespace names are always publicly accessible.

Struct members (Strukturmember)Struct members

Die Member einer Struktur sind die Member, die in der Struktur deklariert sind, sowie die Member, die von der direkten Basisklasse der Struktur System.ValueType und der indirekten Basisklasse geerbt wurden object .The members of a struct are the members declared in the struct and the members inherited from the struct's direct base class System.ValueType and the indirect base class object.

Die Member eines einfachen Typs entsprechen direkt den Membern des Struktur Typs, der durch den einfachen Typ Alias:The members of a simple type correspond directly to the members of the struct type aliased by the simple type:

  • Die Member von sbyte sind die Member der System.SByte Struktur.The members of sbyte are the members of the System.SByte struct.
  • Die Member von byte sind die Member der System.Byte Struktur.The members of byte are the members of the System.Byte struct.
  • Die Member von short sind die Member der System.Int16 Struktur.The members of short are the members of the System.Int16 struct.
  • Die Member von ushort sind die Member der System.UInt16 Struktur.The members of ushort are the members of the System.UInt16 struct.
  • Die Member von int sind die Member der System.Int32 Struktur.The members of int are the members of the System.Int32 struct.
  • Die Member von uint sind die Member der System.UInt32 Struktur.The members of uint are the members of the System.UInt32 struct.
  • Die Member von long sind die Member der System.Int64 Struktur.The members of long are the members of the System.Int64 struct.
  • Die Member von ulong sind die Member der System.UInt64 Struktur.The members of ulong are the members of the System.UInt64 struct.
  • Die Member von char sind die Member der System.Char Struktur.The members of char are the members of the System.Char struct.
  • Die Member von float sind die Member der System.Single Struktur.The members of float are the members of the System.Single struct.
  • Die Member von double sind die Member der System.Double Struktur.The members of double are the members of the System.Double struct.
  • Die Member von decimal sind die Member der System.Decimal Struktur.The members of decimal are the members of the System.Decimal struct.
  • Die Member von bool sind die Member der System.Boolean Struktur.The members of bool are the members of the System.Boolean struct.

EnumerationsmemberEnumeration members

Die Member einer Enumeration sind die Konstanten, die in der-Enumeration deklariert sind, sowie die Member, die von der direkten-Basisklasse der-Enumeration System.Enum und den indirekten Basisklassen und geerbt werden System.ValueType object .The members of an enumeration are the constants declared in the enumeration and the members inherited from the enumeration's direct base class System.Enum and the indirect base classes System.ValueType and object.

KlassenmemberClass members

Die Member einer Klasse sind die Member, die in der Klasse deklariert werden, und die Member, die von der Basisklasse geerbt wurden (mit Ausnahme der Klasse object , die keine Basisklasse aufweist).The members of a class are the members declared in the class and the members inherited from the base class (except for class object which has no base class). Die von der Basisklasse geerbten Member enthalten die Konstanten, Felder, Methoden, Eigenschaften, Ereignisse, Indexer, Operatoren und Typen der Basisklasse, nicht jedoch die Instanzkonstruktoren, destrukturtoren und statischen Konstruktoren der Basisklasse.The members inherited from the base class include the constants, fields, methods, properties, events, indexers, operators, and types of the base class, but not the instance constructors, destructors and static constructors of the base class. Basisklassenmember werden ohne Rücksicht auf ihre Barrierefreiheit geerbt.Base class members are inherited without regard to their accessibility.

Eine Klassen Deklaration kann Deklarationen von Konstanten, Feldern, Methoden, Eigenschaften, Ereignissen, Indexern, Operatoren, Instanzkonstruktoren, Debuggern, statischen Konstruktoren und Typen enthalten.A class declaration may contain declarations of constants, fields, methods, properties, events, indexers, operators, instance constructors, destructors, static constructors and types.

Die Member von object und string entsprechen direkt den Membern der Klassentypen, die Sie Alias:The members of object and string correspond directly to the members of the class types they alias:

  • Die Member von object sind die Member der- System.Object Klasse.The members of object are the members of the System.Object class.
  • Die Member von string sind die Member der- System.String Klasse.The members of string are the members of the System.String class.

Interface members (Schnittstellenmember)Interface members

Die Member einer Schnittstelle sind die Member, die in der-Schnittstelle und in allen Basis Schnittstellen der-Schnittstelle deklariert werden.The members of an interface are the members declared in the interface and in all base interfaces of the interface. Die Member in der Klasse object sind nicht, streng genommen Member einer beliebigen Schnittstelle (Schnittstellenmember).The members in class object are not, strictly speaking, members of any interface (Interface members). Allerdings sind die Member in der Klasse object über die Element Suche in einem beliebigen Schnittstellentyp (Member-Suche) verfügbar.However, the members in class object are available via member lookup in any interface type (Member lookup).

Array members (Arraymember)Array members

Die Member eines Arrays sind die Member, die von der-Klasse geerbt werden System.Array .The members of an array are the members inherited from class System.Array.

DelegatmemberDelegate members

Die Member eines Delegaten sind die Member, die von der-Klasse geerbt werden System.Delegate .The members of a delegate are the members inherited from class System.Delegate.

MemberzugriffMember access

Deklarationen von Membern ermöglichen die Steuerung des Member-Zugriffs.Declarations of members allow control over member access. Der Zugriff auf einen Member wird durch die deklarierte Barrierefreiheit (alsBarrierefreiheit deklariert) des Members in Kombination mit dem Zugriff auf den direkt enthaltenden Typ hergestellt, sofern vorhanden.The accessibility of a member is established by the declared accessibility (Declared accessibility) of the member combined with the accessibility of the immediately containing type, if any.

Wenn der Zugriff auf ein bestimmtes Element zulässig ist, wird der Member als *zugänglich _ bezeichnet.When access to a particular member is allowed, the member is said to be *accessible _. Wenn hingegen der Zugriff auf ein bestimmtes Element nicht zulässig ist, wird der Member als _ * nicht zugänglich* * bezeichnet.Conversely, when access to a particular member is disallowed, the member is said to be _*inaccessible**. Der Zugriff auf ein Mitglied ist zulässig, wenn der Text Speicherort, in dem der Zugriff erfolgt, in der Zugriffs Domäne (Barrierefreiheits Domänen) des Mitglieds enthalten ist.Access to a member is permitted when the textual location in which the access takes place is included in the accessibility domain (Accessibility domains) of the member.

Deklarierter ZugriffDeclared accessibility

Die deklarierte Barrierefreiheit eines Members kann eine der folgenden sein:The declared accessibility of a member can be one of the following:

  • Public, das durch Einschließen eines- public Modifizierers in die Element Deklaration ausgewählt wird.Public, which is selected by including a public modifier in the member declaration. Die intuitive Bedeutung von public ist "Access not Limited".The intuitive meaning of public is "access not limited".
  • Geschützt, das durch Einschließen eines- protected Modifizierers in die Element Deklaration ausgewählt wird.Protected, which is selected by including a protected modifier in the member declaration. Die intuitive Bedeutung von protected ist "der Zugriff ist auf die enthaltende Klasse oder auf Typen beschränkt, die von der enthaltenden Klasse abgeleitet sind".The intuitive meaning of protected is "access limited to the containing class or types derived from the containing class".
  • Intern, das durch Einschließen eines- internal Modifizierers in die Element Deklaration ausgewählt wird.Internal, which is selected by including an internal modifier in the member declaration. Die intuitive Bedeutung von internal ist "Zugriff beschränkt auf dieses Programm".The intuitive meaning of internal is "access limited to this program".
  • Geschützter interner (d.h. geschützt oder intern), der durch Einschließen eines protected -und- internal Modifizierers in die Element Deklaration ausgewählt wird.Protected internal (meaning protected or internal), which is selected by including both a protected and an internal modifier in the member declaration. Die intuitive Bedeutung von protected internal ist "der Zugriff ist auf dieses Programm oder auf Typen beschränkt, die von der enthaltenden Klasse abgeleitet sind".The intuitive meaning of protected internal is "access limited to this program or types derived from the containing class".
  • Privat, das durch Einschließen eines- private Modifizierers in die Element Deklaration ausgewählt wird.Private, which is selected by including a private modifier in the member declaration. Die intuitive Bedeutung von private besteht darin, dass der Zugriff auf den enthaltenden Typ beschränkt ist.The intuitive meaning of private is "access limited to the containing type".

Abhängig vom Kontext, in dem eine Element Deklaration stattfindet, sind nur bestimmte Typen von deklarierter Barrierefreiheit zulässig.Depending on the context in which a member declaration takes place, only certain types of declared accessibility are permitted. Wenn eine Member-Deklaration keine Zugriffsmodifizierer enthält, bestimmt der Kontext, in dem die Deklaration stattfindet, die standardmäßige deklarierte Barrierefreiheit.Furthermore, when a member declaration does not include any access modifiers, the context in which the declaration takes place determines the default declared accessibility.

  • Namespaces verfügen implizit über die public Barrierefreiheit.Namespaces implicitly have public declared accessibility. Für Namespace Deklarationen sind keine Zugriffsmodifizierer zulässig.No access modifiers are allowed on namespace declarations.
  • Typen, die in Kompilierungs Einheiten oder Namespaces deklariert sind, können Zugriff haben public oder internal deklarieren und erhalten standardmäßig internal deklarierten Zugriff.Types declared in compilation units or namespaces can have public or internal declared accessibility and default to internal declared accessibility.
  • Klassenmember können eine der fünf Arten von deklarierten Zugriffsmöglichkeiten aufweisen und erhalten standardmäßig private deklarierte Zugriffsmöglichkeiten.Class members can have any of the five kinds of declared accessibility and default to private declared accessibility. (Beachten Sie, dass ein Typ, der als Member einer Klasse deklariert wird, eine der fünf Arten der deklarierten Barrierefreiheit aufweisen kann, wohingegen ein als Member eines Namespaces deklarierter Typ nur public oder deklariert werden kann internal .)(Note that a type declared as a member of a class can have any of the five kinds of declared accessibility, whereas a type declared as a member of a namespace can have only public or internal declared accessibility.)
  • Strukturmember können public , internal oder private als deklariert werden und erhalten standardmäßig private deklarierten Zugriff, da Strukturen implizit versiegelt sind.Struct members can have public, internal, or private declared accessibility and default to private declared accessibility because structs are implicitly sealed. Strukturmember, die in einer Struktur eingeführt werden (d. h. nicht von dieser Struktur geerbt), dürfen keine protected Barrierefreiheit haben oder protected internal deklarieren.Struct members introduced in a struct (that is, not inherited by that struct) cannot have protected or protected internal declared accessibility. (Beachten Sie, dass ein Typ, der als Member einer Struktur deklariert ist,, public internal oder als private deklariert werden kann, während ein Typ, der als Member eines Namespaces deklariert ist, nur über public oder internal deklarierte Zugriffsmöglichkeiten verfügen kann.)(Note that a type declared as a member of a struct can have public, internal, or private declared accessibility, whereas a type declared as a member of a namespace can have only public or internal declared accessibility.)
  • Schnittstellenmember haben implizit die public Barrierefreiheit deklariert.Interface members implicitly have public declared accessibility. Zugriffsmodifizierer sind für Schnittstellenmember-Deklarationen unzulässigNo access modifiers are allowed on interface member declarations.
  • Enumerationsmember haben implizit " public Barrierefreiheit" deklariert.Enumeration members implicitly have public declared accessibility. Es sind keine Zugriffsmodifizierer für Enumerationsmember zulässig.No access modifiers are allowed on enumeration member declarations.

Barrierefreiheits DomänenAccessibility domains

Die *Barrierefreiheits Domäne _ eines Members besteht aus den (möglicherweise zusammenhängenden) Abschnitten von Programmtext, in dem der Zugriff auf den Member zulässig ist.The *accessibility domain _ of a member consists of the (possibly disjoint) sections of program text in which access to the member is permitted. Zum Definieren der Zugriffs Domäne eines Members wird ein Member als oberste Ebene bezeichnet, wenn er nicht innerhalb eines Typs deklariert ist, und ein Member wird als geschachtelt bezeichnet, wenn er ** in einem anderen Typ deklariert wird.For purposes of defining the accessibility domain of a member, a member is said to be top-level if it is not declared within a type, and a member is said to be nested if it is declared within another type. Außerdem wird der Programm Text eines Programms als sämtlicher Programmtext definiert, der in allen Quelldateien des Programms enthalten ist, und der Programmtext eines Typs wird als sämtlicher Programmtext definiert, der in den _type_declaration * s dieses Typs enthalten ist (einschließlich, eventuell Typen, die innerhalb des Typs geschachtelt sind).Furthermore, the program text of a program is defined as all program text contained in all source files of the program, and the program text of a type is defined as all program text contained in the _type_declaration*s of that type (including, possibly, types that are nested within the type).

Die Zugriffs Domäne eines vordefinierten Typs (z. b object int ., oder double ) ist unbegrenzt.The accessibility domain of a predefined type (such as object, int, or double) is unlimited.

Die Zugriffs Domäne eines ungebundenen Typs der obersten Ebene T (gebundene und ungebundene Typen), die in einem Programm deklariert ist, P wird wie folgt definiert:The accessibility domain of a top-level unbound type T (Bound and unbound types) that is declared in a program P is defined as follows:

  • Wenn die deklarierte Zugriffsart von den Wert T public hat, entspricht die Zugriffs Domäne von T dem Programmtext von P und jedem Programm, das auf verweist P .If the declared accessibility of T is public, the accessibility domain of T is the program text of P and any program that references P.
  • Wenn die deklarierte Zugriffsart von T den Wert internal hat, entspricht die Zugriffsdomäne von T dem Programmtext von P.If the declared accessibility of T is internal, the accessibility domain of T is the program text of P.

Aus diesen Definitionen folgt, dass die Zugriffs Domäne eines ungebundenen Typs der obersten Ebene immer mindestens dem Programmtext des Programms entspricht, in dem der Typ deklariert ist.From these definitions it follows that the accessibility domain of a top-level unbound type is always at least the program text of the program in which that type is declared.

Die Zugriffs Domäne für einen konstruierten Typ T<A1, ..., An> ist die Schnittmenge der Barrierefreiheits Domäne des ungebundenen generischen Typs T und der Barrierefreiheits Domänen der Typargumente A1, ..., An .The accessibility domain for a constructed type T<A1, ..., An> is the intersection of the accessibility domain of the unbound generic type T and the accessibility domains of the type arguments A1, ..., An.

Die Zugriffs Domäne eines geschachtelten Members, der M in einem Typ T innerhalb eines Programms deklariert P ist, wird wie folgt definiert (es M kann sein, dass selbst ein Typ sein kann):The accessibility domain of a nested member M declared in a type T within a program P is defined as follows (noting that M itself may possibly be a type):

  • Wenn die deklarierte Zugriffsart von M den Wert public hat, entspricht die Zugriffsdomäne von M der von T.If the declared accessibility of M is public, the accessibility domain of M is the accessibility domain of T.
  • Wenn die deklarierte Zugriffsart von den Wert M protected internal hat, kann der D Programmtext von P und der Programmtext eines beliebigen Typs sein, der von abgeleitet wird T , der außerhalb von deklariert wurde P .If the declared accessibility of M is protected internal, let D be the union of the program text of P and the program text of any type derived from T, which is declared outside P. Die Zugriffs Domäne von M ist die Schnittmenge der Zugriffs Domäne von T mit D .The accessibility domain of M is the intersection of the accessibility domain of T with D.
  • Wenn die deklarierte Zugriffsart von den Wert M protected hat, können Sie den D Programmtext von T und den Programmtext eines beliebigen Typs, der von abgeleitet ist, darstellen T .If the declared accessibility of M is protected, let D be the union of the program text of T and the program text of any type derived from T. Die Zugriffs Domäne von M ist die Schnittmenge der Zugriffs Domäne von T mit D .The accessibility domain of M is the intersection of the accessibility domain of T with D.
  • Wenn die deklarierte Zugriffsart von M den Wert internal hat, entspricht die Zugriffsdomäne von M der Schnittmenge zwischen der Zugriffsdomäne von T und dem Programmtext von P.If the declared accessibility of M is internal, the accessibility domain of M is the intersection of the accessibility domain of T with the program text of P.
  • Wenn die deklarierte Zugriffsart von M den Wert private hat, entspricht die Zugriffsdomäne von M dem Programmtext von T.If the declared accessibility of M is private, the accessibility domain of M is the program text of T.

Aus diesen Definitionen folgt, dass die Barrierefreiheits Domäne eines in einem Bereich eingefügten Members immer mindestens dem Programmtext des Typs entspricht, in dem der Member deklariert ist.From these definitions it follows that the accessibility domain of a nested member is always at least the program text of the type in which the member is declared. Ferner folgt, dass die Zugriffs Domäne eines Members nie inklusiver ist als die Zugriffs Domäne des Typs, in dem der Member deklariert ist.Furthermore, it follows that the accessibility domain of a member is never more inclusive than the accessibility domain of the type in which the member is declared.

Wenn auf einen Typ oder Member M zugegriffen wird, werden die folgenden Schritte in intuitiver Hinsicht ausgewertet, um sicherzustellen, dass der Zugriff zulässig ist:In intuitive terms, when a type or member M is accessed, the following steps are evaluated to ensure that the access is permitted:

  • Wenn als erstes M innerhalb eines Typs deklariert wird (im Gegensatz zu einer Kompilierungseinheit oder einem Namespace), tritt ein Kompilierzeitfehler auf, wenn auf diesen Typ nicht zugegriffen werden kann.First, if M is declared within a type (as opposed to a compilation unit or a namespace), a compile-time error occurs if that type is not accessible.
  • Wenn den Wert M public hat, ist der Zugriff zulässig.Then, if M is public, the access is permitted.
  • Andernfalls, wenn M protected internal den Wert hat, ist der Zugriff zulässig, wenn er innerhalb des Programms auftritt, in dem M deklariert ist, oder wenn es in einer von der-Klasse abgeleiteten Klasse auftritt, in der M deklariert wird und durch den abgeleiteten Klassentyp (geschützter Zugriff für Instanzmember) erfolgt.Otherwise, if M is protected internal, the access is permitted if it occurs within the program in which M is declared, or if it occurs within a class derived from the class in which M is declared and takes place through the derived class type (Protected access for instance members).
  • Andernfalls, wenn M protected den Wert hat, ist der Zugriff zulässig, wenn er innerhalb der Klasse auftritt, in der M deklariert ist, oder wenn er in einer von der-Klasse abgeleiteten Klasse auftritt, in der M deklariert ist und durch den abgeleiteten Klassentyp (geschützter Zugriff für Instanzmember) erfolgt.Otherwise, if M is protected, the access is permitted if it occurs within the class in which M is declared, or if it occurs within a class derived from the class in which M is declared and takes place through the derived class type (Protected access for instance members).
  • Andernfalls, wenn M internal den Wert hat, ist der Zugriff zulässig, wenn er innerhalb des Programms, in dem M deklariert ist, auftritt.Otherwise, if M is internal, the access is permitted if it occurs within the program in which M is declared.
  • Andernfalls, wenn M private den Wert hat, ist der Zugriff zulässig, wenn er innerhalb des Typs auftritt, in dem M deklariert ist.Otherwise, if M is private, the access is permitted if it occurs within the type in which M is declared.
  • Andernfalls ist der Typ oder Member nicht zugänglich, und es tritt ein Kompilierzeitfehler auf.Otherwise, the type or member is inaccessible, and a compile-time error occurs.

Im BeispielIn the example

public class A
{
    public static int X;
    internal static int Y;
    private static int Z;
}

internal class B
{
    public static int X;
    internal static int Y;
    private static int Z;

    public class C
    {
        public static int X;
        internal static int Y;
        private static int Z;
    }

    private class D
    {
        public static int X;
        internal static int Y;
        private static int Z;
    }
}

die Klassen und Member haben die folgenden Barrierefreiheits Domänen:the classes and members have the following accessibility domains:

  • Die Zugriffs Domäne von A und A.X ist unbegrenzt.The accessibility domain of A and A.X is unlimited.
  • Die Zugriffs Domäne von A.Y , B , B.X , B.Y , B.C , B.C.X und B.C.Y ist der Programmtext des enthaltenden Programms.The accessibility domain of A.Y, B, B.X, B.Y, B.C, B.C.X, and B.C.Y is the program text of the containing program.
  • Die Zugriffs Domäne von A.Z ist der Programmtext von A .The accessibility domain of A.Z is the program text of A.
  • Die Zugriffs Domäne von B.Z und B.D ist der Programmtext von B , einschließlich des Programm Texts von B.C und B.D .The accessibility domain of B.Z and B.D is the program text of B, including the program text of B.C and B.D.
  • Die Zugriffs Domäne von B.C.Z ist der Programmtext von B.C .The accessibility domain of B.C.Z is the program text of B.C.
  • Die Zugriffs Domäne von B.D.X und B.D.Y ist der Programmtext von B , einschließlich des Programm Texts von B.C und B.D .The accessibility domain of B.D.X and B.D.Y is the program text of B, including the program text of B.C and B.D.
  • Die Zugriffs Domäne von B.D.Z ist der Programmtext von B.D .The accessibility domain of B.D.Z is the program text of B.D.

Wie das Beispiel zeigt, ist die Zugriffs Domäne eines Members nie größer als die eines enthaltenden Typs.As the example illustrates, the accessibility domain of a member is never larger than that of a containing type. Wenn z. b. alle Member X öffentlich deklarierte Barrierefreiheit haben, verfügen alle außer A.X über Barrierefreiheits Domänen, die durch einen enthaltenden Typ eingeschränkt werden.For example, even though all X members have public declared accessibility, all but A.X have accessibility domains that are constrained by a containing type.

Wie in Membersbeschrieben, werden alle Member einer Basisklasse, mit Ausnahme von Instanzkonstruktoren, destrukturiertoren und statischen Konstruktoren, von abgeleiteten Typen geerbt.As described in Members, all members of a base class, except for instance constructors, destructors and static constructors, are inherited by derived types. Dies schließt sogar private Member einer Basisklasse ein.This includes even private members of a base class. Die Zugriffs Domäne eines privaten Members enthält jedoch nur den Programmtext des Typs, in dem der Member deklariert ist.However, the accessibility domain of a private member includes only the program text of the type in which the member is declared. Im BeispielIn the example

class A
{
    int x;

    static void F(B b) {
        b.x = 1;        // Ok
    }
}

class B: A
{
    static void F(B b) {
        b.x = 1;        // Error, x not accessible
    }
}

die- B Klasse erbt den privaten Member x von der- A Klasse.the B class inherits the private member x from the A class. Da der Member privat ist, kann nur innerhalb der class_body von darauf zugegriffen werden A .Because the member is private, it is only accessible within the class_body of A. Folglich ist der Zugriff auf b.x in der- A.F Methode erfolgreich, schlägt in der-Methode jedoch fehl B.F .Thus, the access to b.x succeeds in the A.F method, but fails in the B.F method.

Geschützter Zugriff für InstanzmemberProtected access for instance members

Wenn auf einen protected Instanzmember außerhalb des Programm Texts der Klasse zugegriffen wird, in der er deklariert ist, und wenn protected internal auf einen Instanzmember außerhalb des Programm Texts des Programms zugegriffen wird, in dem es deklariert ist, muss der Zugriff innerhalb einer Klassen Deklaration erfolgen, die von der Klasse abgeleitet ist, in der Sie deklariert ist.When a protected instance member is accessed outside the program text of the class in which it is declared, and when a protected internal instance member is accessed outside the program text of the program in which it is declared, the access must take place within a class declaration that derives from the class in which it is declared. Darüber hinaus muss der Zugriff durch eine Instanz dieses abgeleiteten Klassen Typs oder eines aus der Klasse erstellten Klassen Typs erfolgen.Furthermore, the access is required to take place through an instance of that derived class type or a class type constructed from it. Diese Einschränkung verhindert, dass eine abgeleitete Klasse auf geschützte Member anderer abgeleiteter Klassen zugreift, auch wenn die Elemente von derselben Basisklasse geerbt werden.This restriction prevents one derived class from accessing protected members of other derived classes, even when the members are inherited from the same base class.

Dabei handelt es sich um B eine Basisklasse, die einen geschützten Instanzmember deklariert M , und D eine Klasse, die von abgeleitet wird B .Let B be a base class that declares a protected instance member M, and let D be a class that derives from B. In der class_body von D kann der Zugriff auf M eine der folgenden Formen annehmen:Within the class_body of D, access to M can take one of the following forms:

  • Eine nicht qualifizierte TYPE_NAME oder primary_expression des Formulars M .An unqualified type_name or primary_expression of the form M.
  • Eine primary_expression des Formulars E.M , bereitgestellt, wenn der Typ von E T oder eine von abgeleitete Klasse ist, T wobei T der Klassentyp D oder ein Klassentyp ist, der aus erstellt wurde. DA primary_expression of the form E.M, provided the type of E is T or a class derived from T, where T is the class type D, or a class type constructed from D
  • Eine primary_expression des Formulars base.M .A primary_expression of the form base.M.

Zusätzlich zu diesen Zugriffs Formen kann eine abgeleitete Klasse auf einen geschützten Instanzkonstruktor einer Basisklasse in einer constructor_initializer (Konstruktorinitialisierer) zugreifen.In addition to these forms of access, a derived class can access a protected instance constructor of a base class in a constructor_initializer (Constructor initializers).

Im BeispielIn the example

public class A
{
    protected int x;

    static void F(A a, B b) {
        a.x = 1;        // Ok
        b.x = 1;        // Ok
    }
}

public class B: A
{
    static void F(A a, B b) {
        a.x = 1;        // Error, must access through instance of B
        b.x = 1;        // Ok
    }
}

in A ist es möglich, x über Instanzen von A und B auf zuzugreifen, da der Zugriff in beiden Fällen durch eine Instanz von A oder eine von abgeleitete Klasse erfolgt A .within A, it is possible to access x through instances of both A and B, since in either case the access takes place through an instance of A or a class derived from A. In B ist es jedoch nicht möglich, auf x über eine Instanz von zuzugreifen A , da A nicht von abgeleitet ist B .However, within B, it is not possible to access x through an instance of A, since A does not derive from B.

Im BeispielIn the example

class C<T>
{
    protected T x;
}

class D<T>: C<T>
{
    static void F() {
        D<T> dt = new D<T>();
        D<int> di = new D<int>();
        D<string> ds = new D<string>();
        dt.x = default(T);
        di.x = 123;
        ds.x = "test";
    }
}

die drei Zuweisungen zu x sind zulässig, da Sie alle durch Instanzen von Klassentypen erfolgen, die aus dem generischen Typ erstellt werden.the three assignments to x are permitted because they all take place through instances of class types constructed from the generic type.

Barrierefreiheits EinschränkungenAccessibility constraints

Mehrere Konstrukte in der Programmiersprache c# erfordern, dass ein Typ mindestens so zugänglich ist wie ein Member oder ein anderer Typ.Several constructs in the C# language require a type to be at least as accessible as a member or another type. Ein Typ T ist mindestens so zugänglich wie ein Member oder Typ, M Wenn die Zugriffs Domäne von T eine supermenge der Zugriffs Domäne von ist M .A type T is said to be at least as accessible as a member or type M if the accessibility domain of T is a superset of the accessibility domain of M. Mit anderen Worten: T ist zumindest so zugänglich wie, M Wenn T in allen Kontexten, auf die zugegriffen werden kann, zugänglich ist M .In other words, T is at least as accessible as M if T is accessible in all contexts in which M is accessible.

Die folgenden Barrierefreiheits Einschränkungen sind vorhanden:The following accessibility constraints exist:

  • Die direkte Basisklasse eines Klassentyps muss mindesten dieselben Zugriffsmöglichkeiten wie der Klassentyp selbst bieten.The direct base class of a class type must be at least as accessible as the class type itself.
  • Die explizite Basisschnittstelle eines Schnittstellentyps muss mindesten dieselben Zugriffsmöglichkeiten bieten wie der Schnittstellentyp selbst.The explicit base interfaces of an interface type must be at least as accessible as the interface type itself.
  • Die Rückgabe- und Parametertypen eines Delegattyps müssen mindestens dieselben Zugriffsmöglichkeiten wie der Delegattyp selbst bieten.The return type and parameter types of a delegate type must be at least as accessible as the delegate type itself.
  • Der Typ einer Konstante muss mindestens dieselben Zugriffsmöglichkeiten wie die Konstante selbst bieten.The type of a constant must be at least as accessible as the constant itself.
  • Der Typ eines Felds muss mindestens dieselben Zugriffsmöglichkeiten bieten wie das Feld selbst.The type of a field must be at least as accessible as the field itself.
  • Die Rückgabe- und Parametertypen einer Methode müssen mindestens dieselben Zugriffsmöglichkeiten bieten wie die Methode selbst.The return type and parameter types of a method must be at least as accessible as the method itself.
  • Der Typ einer Eigenschaft muss mindestens dieselben Zugriffsmöglichkeiten bieten wie die Eigenschaft selbst.The type of a property must be at least as accessible as the property itself.
  • Der Typ eines Ereignisses muss mindestens dieselben Zugriffsmöglichkeiten bieten wie das Ereignis selbst.The type of an event must be at least as accessible as the event itself.
  • Der Typ und die Parametertypen eines Indexers müssen mindestens dieselben Zugriffsmöglichkeiten bieten wie der Indexer selbst.The type and parameter types of an indexer must be at least as accessible as the indexer itself.
  • Die Rückgabe- und Parametertypen eines Operators müssen mindestens dieselben Zugriffsmöglichkeiten bieten wie der Operator selbst.The return type and parameter types of an operator must be at least as accessible as the operator itself.
  • Die Parametertypen eines Instanzkonstruktors müssen mindestens so zugänglich sein wie der Instanzkonstruktor selbst.The parameter types of an instance constructor must be at least as accessible as the instance constructor itself.

Im BeispielIn the example

class A {...}

public class B: A {...}

die B -Klasse führt zu einem Kompilierzeitfehler, da A nicht mindestens so zugänglich ist wie B .the B class results in a compile-time error because A is not at least as accessible as B.

Gleiches gilt für das BeispielLikewise, in the example

class A {...}

public class B
{
    A F() {...}

    internal A G() {...}

    public A H() {...}
}

die H -Methode in B führt zu einem Kompilierzeitfehler, da der Rückgabetyp A nicht mindestens so zugänglich ist wie die-Methode.the H method in B results in a compile-time error because the return type A is not at least as accessible as the method.

Signatures and overloading (Signaturen und Überladen)Signatures and overloading

Methoden, Instanzkonstruktoren, Indexer und Operatoren sind durch ihre Signaturen gekennzeichnet:Methods, instance constructors, indexers, and operators are characterized by their signatures:

  • Die Signatur einer Methode besteht aus dem Namen der Methode, der Anzahl der Typparameter und dem Typ und der Art (Wert, Verweis oder Ausgabe) der einzelnen formalen Parameter, die in der Reihenfolge von links nach rechts berücksichtigt werden.The signature of a method consists of the name of the method, the number of type parameters and the type and kind (value, reference, or output) of each of its formal parameters, considered in the order left to right. Zu diesem Zweck wird jeder Typparameter der Methode, die im Typ eines formalen Parameters vorkommt, nicht anhand seines Namens identifiziert, sondern anhand seiner Ordinalposition in der Typargument Liste der Methode.For these purposes, any type parameter of the method that occurs in the type of a formal parameter is identified not by its name, but by its ordinal position in the type argument list of the method. Die Signatur einer Methode enthält nicht den Rückgabetyp, den params Modifizierer, der für den ganz rechts Esten Parameter angegeben werden kann, oder die optionalen Typparameter Einschränkungen.The signature of a method specifically does not include the return type, the params modifier that may be specified for the right-most parameter, nor the optional type parameter constraints.
  • Die Signatur eines Instanzkonstruktors besteht aus Typ und Art (Wert, Verweis oder Ausgabe) der einzelnen formalen Parameter, die in der Reihenfolge von links nach rechts berücksichtigt werden.The signature of an instance constructor consists of the type and kind (value, reference, or output) of each of its formal parameters, considered in the order left to right. Die Signatur eines Instanzkonstruktors schließt speziell den params Modifizierer nicht ein, der für den ganz rechts Esten Parameter angegeben werden kann.The signature of an instance constructor specifically does not include the params modifier that may be specified for the right-most parameter.
  • Die Signatur eines Indexers besteht aus dem Typ der einzelnen formalen Parameter, die in der Reihenfolge von links nach rechts berücksichtigt werden.The signature of an indexer consists of the type of each of its formal parameters, considered in the order left to right. Die Signatur eines Indexers enthält weder den Elementtyp noch den params Modifizierer, der für den ganz rechts Esten Parameter angegeben werden kann.The signature of an indexer specifically does not include the element type, nor does it include the params modifier that may be specified for the right-most parameter.
  • Die Signatur eines Operators besteht aus dem Namen des Operators und dem Typ der einzelnen formalen Parameter, die in der Reihenfolge von links nach rechts betrachtet werden.The signature of an operator consists of the name of the operator and the type of each of its formal parameters, considered in the order left to right. Die Signatur eines Operators schließt den Ergebnistyp nicht ein.The signature of an operator specifically does not include the result type.

Signaturen sind der aktivierende Mechanismus für das überladen von Membern in Klassen, Strukturen und Schnittstellen:Signatures are the enabling mechanism for overloading of members in classes, structs, and interfaces:

  • Das Überladen von Methoden ermöglicht einer Klasse, Struktur oder Schnittstelle das Deklarieren mehrerer Methoden mit demselben Namen, vorausgesetzt, ihre Signaturen sind innerhalb dieser Klasse, Struktur oder Schnittstelle eindeutig.Overloading of methods permits a class, struct, or interface to declare multiple methods with the same name, provided their signatures are unique within that class, struct, or interface.
  • Das Überladen von Instanzkonstruktoren ermöglicht einer Klasse oder Struktur das Deklarieren mehrerer Instanzkonstruktoren, vorausgesetzt, ihre Signaturen sind innerhalb dieser Klasse oder Struktur eindeutig.Overloading of instance constructors permits a class or struct to declare multiple instance constructors, provided their signatures are unique within that class or struct.
  • Das Überladen von indexatoren ermöglicht es einer Klasse, Struktur oder Schnittstelle, mehrere Indexer zu deklarieren, vorausgesetzt, ihre Signaturen sind innerhalb dieser Klasse, Struktur oder Schnittstelle eindeutig.Overloading of indexers permits a class, struct, or interface to declare multiple indexers, provided their signatures are unique within that class, struct, or interface.
  • Das Überladen von Operatoren ermöglicht einer Klasse oder Struktur das Deklarieren mehrerer Operatoren mit demselben Namen, vorausgesetzt, ihre Signaturen sind innerhalb dieser Klasse oder Struktur eindeutig.Overloading of operators permits a class or struct to declare multiple operators with the same name, provided their signatures are unique within that class or struct.

Obwohl out und ref Parametermodifizierer als Teil einer Signatur angesehen werden, können in einem einzelnen Typ deklarierte Member nicht in der Signatur ausschließlich von ref und abweichen out .Although out and ref parameter modifiers are considered part of a signature, members declared in a single type cannot differ in signature solely by ref and out. Ein Kompilierzeitfehler tritt auf, wenn zwei Member im gleichen Typ mit Signaturen deklariert werden, die identisch wären, wenn alle Parameter in beiden Methoden mit out modifiziererelementen in ref Modifizierer geändert wurden.A compile-time error occurs if two members are declared in the same type with signatures that would be the same if all parameters in both methods with out modifiers were changed to ref modifiers. Für andere Zwecke der Signatur Übereinstimmung (z. b. ausblenden oder überschreiben) ref out werden und als Teil der Signatur angesehen und stimmen nicht mit einander überein.For other purposes of signature matching (e.g., hiding or overriding), ref and out are considered part of the signature and do not match each other. (Diese Einschränkung besteht darin, dass c#-Programme auf einfache Weise für die Common Language Infrastructure (CLI) übersetzt werden können, die keine Möglichkeit bietet, Methoden zu definieren, die sich ausschließlich in und unterscheiden ref out .)(This restriction is to allow C#  programs to be easily translated to run on the Common Language Infrastructure (CLI), which does not provide a way to define methods that differ solely in ref and out.)

Für Signaturen werden die Typen object und dynamic als identisch betrachtet.For the purposes of signatures, the types object and dynamic are considered the same. Member, die in einem einzelnen Typ deklariert werden, können sich daher nicht in der Signatur ausschließlich durch und unterscheiden object dynamic .Members declared in a single type can therefore not differ in signature solely by object and dynamic.

Das folgende Beispiel zeigt eine Reihe von überladenen Methoden Deklarationen zusammen mit ihren Signaturen.The following example shows a set of overloaded method declarations along with their signatures.

interface ITest
{
    void F();                        // F()

    void F(int x);                   // F(int)

    void F(ref int x);               // F(ref int)

    void F(out int x);               // F(out int)      error

    void F(int x, int y);            // F(int, int)

    int F(string s);                 // F(string)

    int F(int x);                    // F(int)          error

    void F(string[] a);              // F(string[])

    void F(params string[] a);       // F(string[])     error
}

Beachten Sie, dass alle ref -und- out Parametermodifizierer (Methoden Parameter) Teil einer Signatur sind.Note that any ref and out parameter modifiers (Method parameters) are part of a signature. Daher F(int) sind und F(ref int) eindeutige Signaturen.Thus, F(int) and F(ref int) are unique signatures. F(ref int)Und können jedoch F(out int) nicht innerhalb derselben Schnittstelle deklariert werden, da sich Ihre Signaturen ausschließlich durch und unterscheiden ref out .However, F(ref int) and F(out int) cannot be declared within the same interface because their signatures differ solely by ref and out. Beachten Sie außerdem, dass der Rückgabetyp und der- params Modifizierer nicht Teil einer Signatur sind. Daher ist es nicht möglich, nur auf der Grundlage des Rückgabe Typs oder auf das einschließen oder ausschließen des params Modifizierers zu überlasten.Also, note that the return type and the params modifier are not part of a signature, so it is not possible to overload solely based on return type or on the inclusion or exclusion of the params modifier. Daher führen die Deklarationen der F(int) F(params string[]) oben genannten Methoden zu einem Kompilierzeitfehler.As such, the declarations of the methods F(int) and F(params string[]) identified above result in a compile-time error.

BereicheScopes

Der *Bereich _ eines Namens ist der Bereich des Programm Texts, in dem auf die durch den Namen deklarierte Entität verwiesen werden kann, ohne dass der Name qualifiziert ist.The *scope _ of a name is the region of program text within which it is possible to refer to the entity declared by the name without qualification of the name. Bereiche können geschachtelt werden, und ein innerer Bereich kann die Bedeutung eines Namens aus einem äußeren Gültigkeitsbereich neu deklarieren (Dies bedeutet jedoch nicht, dass die Einschränkung, die von Deklarationen aufgrund von Deklarationen in einem geschachtelten Block festgelegt wird, nicht möglich ist, eine lokale Variable mit dem gleichen Namen wie eine lokale Variable in einem einschließenden Block zu deklarieren).Scopes can be nested, and an inner scope may redeclare the meaning of a name from an outer scope (this does not, however, remove the restriction imposed by Declarations that within a nested block it is not possible to declare a local variable with the same name as a local variable in an enclosing block). Der Name aus dem äußeren Gültigkeitsbereich wird dann als _ Hidden* in der vom inneren Bereich behandelten Programmtext angezeigt, und der Zugriff auf den äußeren Namen ist nur durch Qualifizierung des Namens möglich.The name from the outer scope is then said to be _ hidden* in the region of program text covered by the inner scope, and access to the outer name is only possible by qualifying the name.

  • Der Gültigkeitsbereich eines von einem namespace_member_declaration (Namespace Members) deklarierten Namespace Members ohne einschließende namespace_declaration ist der gesamte Programmtext.The scope of a namespace member declared by a namespace_member_declaration (Namespace members) with no enclosing namespace_declaration is the entire program text.
  • Der Gültigkeitsbereich eines Namespace Members, der von einem namespace_member_declaration in einem namespace_declaration deklariert wird, dessen voll qualifizierter Name N der namespace_body jedes namespace_declaration ist, dessen voll qualifizierter Name ist N N , gefolgt von einem Zeitraum.The scope of a namespace member declared by a namespace_member_declaration within a namespace_declaration whose fully qualified name is N is the namespace_body of every namespace_declaration whose fully qualified name is N or starts with N, followed by a period.
  • Der durch eine extern_alias_directive definierte Bereich des Namens erstreckt sich über die using_directive s, global_attributes und namespace_member_declaration n der unmittelbar enthaltenden Kompilierungseinheit oder des Namespace Texts.The scope of name defined by an extern_alias_directive extends over the using_directive s, global_attributes and namespace_member_declaration s of its immediately containing compilation unit or namespace body. Ein extern_alias_directive führt keine neuen Member zum zugrunde liegenden Deklarations Bereich ein.An extern_alias_directive does not contribute any new members to the underlying declaration space. Anders ausgedrückt: eine extern_alias_directive ist nicht transitiv, sondern wirkt sich nur auf die Kompilierungseinheit oder den Namespace Körper aus, in der Sie auftritt.In other words, an extern_alias_directive is not transitive, but, rather, affects only the compilation unit or namespace body in which it occurs.
  • Der Gültigkeitsbereich eines Namens, der von einem using_directive definiert oder importiert wird (using-Direktiven), erstreckt sich über die namespace_member_declaration s der compilation_unit oder namespace_body , in der der using_directive auftritt.The scope of a name defined or imported by a using_directive (Using directives) extends over the namespace_member_declaration s of the compilation_unit or namespace_body in which the using_directive occurs. Eine using_directive kann NULL oder mehr Namespace-, Typ-oder Elementnamen innerhalb eines bestimmten compilation_unit oder namespace_body bereitstellen, führt jedoch keine neuen Member zum zugrunde liegenden Deklarations Bereich.A using_directive may make zero or more namespace, type or member names available within a particular compilation_unit or namespace_body, but does not contribute any new members to the underlying declaration space. Anders ausgedrückt: eine using_directive ist nicht transitiv, sondern wirkt sich nur auf die compilation_unit oder namespace_body aus, in der Sie auftritt.In other words, a using_directive is not transitive but rather affects only the compilation_unit or namespace_body in which it occurs.
  • Der Gültigkeitsbereich eines Typparameters, der von einer type_parameter_list in einer class_declaration deklariert wird (Klassen Deklarationen), ist die class_base, type_parameter_constraints_clause s und class_body dieser class_declaration.The scope of a type parameter declared by a type_parameter_list on a class_declaration (Class declarations) is the class_base, type_parameter_constraints_clause s, and class_body of that class_declaration.
  • Der Gültigkeitsbereich eines Typparameters, der von einer type_parameter_list in einer struct_declaration (Struktur Deklarationen) deklariert wird, ist die struct_interfaces, type_parameter_constraints_clause s und struct_body dieser struct_declaration.The scope of a type parameter declared by a type_parameter_list on a struct_declaration (Struct declarations) is the struct_interfaces, type_parameter_constraints_clause s, and struct_body of that struct_declaration.
  • Der Gültigkeitsbereich eines Typparameters, der durch eine type_parameter_list in einem interface_declaration (Schnittstellen Deklarationen) deklariert wird, ist die interface_base, type_parameter_constraints_clause s und interface_body dieser interface_declaration.The scope of a type parameter declared by a type_parameter_list on an interface_declaration (Interface declarations) is the interface_base, type_parameter_constraints_clause s, and interface_body of that interface_declaration.
  • Der Gültigkeitsbereich eines Typparameters, der von einer type_parameter_list in einer delegate_declaration deklariert wird (Delegatdeklarationen), ist die return_type, formal_parameter_list und type_parameter_constraints_clause e dieses delegate_declaration.The scope of a type parameter declared by a type_parameter_list on a delegate_declaration (Delegate declarations) is the return_type, formal_parameter_list, and type_parameter_constraints_clause s of that delegate_declaration.
  • Der Gültigkeitsbereich eines Members, der von einem class_member_declaration (Klassen Text) deklariert wird, ist die class_body , in der die Deklaration erfolgt.The scope of a member declared by a class_member_declaration (Class body) is the class_body in which the declaration occurs. Außerdem erstreckt sich der Gültigkeitsbereich eines Klassenmembers auf die class_body der abgeleiteten Klassen, die in der Zugriffs Domäne (Barrierefreiheits Domänen) des Members enthalten sind.In addition, the scope of a class member extends to the class_body of those derived classes that are included in the accessibility domain (Accessibility domains) of the member.
  • Der Gültigkeitsbereich eines Members, der von einem struct_member_declaration (Strukturmember) deklariert wird, ist die struct_body , in der die Deklaration erfolgt.The scope of a member declared by a struct_member_declaration (Struct members) is the struct_body in which the declaration occurs.
  • Der Gültigkeitsbereich eines Members, der von einem enum_member_declaration (Enumerationsmember) deklariert wird, ist die enum_body , in der die Deklaration erfolgt.The scope of a member declared by an enum_member_declaration (Enum members) is the enum_body in which the declaration occurs.
  • Der Gültigkeitsbereich eines in einem method_declaration (Methoden) deklarierten Parameters ist die method_body dieser method_declaration.The scope of a parameter declared in a method_declaration (Methods) is the method_body of that method_declaration.
  • Der Gültigkeitsbereich eines in einem indexer_declaration (Indexer) deklarierten Parameters ist die accessor_declarations dieser indexer_declaration.The scope of a parameter declared in an indexer_declaration (Indexers) is the accessor_declarations of that indexer_declaration.
  • Der Gültigkeitsbereich eines in einem operator_declaration (Operatoren) deklarierten Parameters ist der Block dieser operator_declaration.The scope of a parameter declared in an operator_declaration (Operators) is the block of that operator_declaration.
  • Der Gültigkeitsbereich eines in einem constructor_declaration (Instanzkonstruktors) deklarierten Parameters ist der constructor_initializer und Block von constructor_declaration.The scope of a parameter declared in a constructor_declaration (Instance constructors) is the constructor_initializer and block of that constructor_declaration.
  • Der Gültigkeitsbereich eines in einem lambda_expression (anonymen Funktions Ausdruck) deklarierten Parameters ist die anonymous_function_body dieser lambda_expressionThe scope of a parameter declared in a lambda_expression (Anonymous function expressions) is the anonymous_function_body of that lambda_expression
  • Der Gültigkeitsbereich eines in einem anonymous_method_expression (anonymen Funktions Ausdruck) deklarierten Parameters ist der Block dieser anonymous_method_expression.The scope of a parameter declared in an anonymous_method_expression (Anonymous function expressions) is the block of that anonymous_method_expression.
  • Der Gültigkeitsbereich einer Bezeichnung, die in einer labeled_statement deklariert ist (Anweisungen mit Bezeichnung), ist der Block , in dem die Deklaration auftritt.The scope of a label declared in a labeled_statement (Labeled statements) is the block in which the declaration occurs.
  • Der Gültigkeitsbereich einer lokalen Variablen, die in einem local_variable_declaration deklariert ist (Deklarationen von lokalen Variablen), ist der Block, in dem die Deklaration auftritt.The scope of a local variable declared in a local_variable_declaration (Local variable declarations) is the block in which the declaration occurs.
  • Der Gültigkeitsbereich einer lokalen Variablen, die in einem switch_block einer- switch Anweisung (der Switch-Anweisung) deklariert ist, ist die switch_block.The scope of a local variable declared in a switch_block of a switch statement (The switch statement) is the switch_block.
  • Der Gültigkeitsbereich einer lokalen Variablen, die in einem for_initializer einer- for Anweisung (der for-Anweisung) deklariert wurde, ist die for_initializer, die for_condition, die for_iterator und die enthaltene Anweisung der for Anweisung.The scope of a local variable declared in a for_initializer of a for statement (The for statement) is the for_initializer, the for_condition, the for_iterator, and the contained statement of the for statement.
  • Der Gültigkeitsbereich einer lokalen Konstante, die in einer local_constant_declaration (lokale Konstante Deklarationen) deklariert ist, ist der Block, in dem die Deklaration auftritt.The scope of a local constant declared in a local_constant_declaration (Local constant declarations) is the block in which the declaration occurs. Es handelt sich um einen Kompilierzeitfehler, der auf eine lokale Konstante in einer Textposition verweist, die dem constant_declarator vorangestellt ist.It is a compile-time error to refer to a local constant in a textual position that precedes its constant_declarator.
  • Der Gültigkeitsbereich einer Variablen, die als Teil einer foreach_statement, using_statement lock_statement oder query_expression deklariert wird, wird durch die Erweiterung des angegebenen Konstrukts bestimmt.The scope of a variable declared as part of a foreach_statement, using_statement, lock_statement or query_expression is determined by the expansion of the given construct.

Innerhalb des Gültigkeits Bereichs eines Namespace, einer Klasse, einer Struktur oder eines Enumerationsmembers kann auf das Element in einer Textposition verwiesen werden, die der Deklaration des Members vorangestellt ist.Within the scope of a namespace, class, struct, or enumeration member it is possible to refer to the member in a textual position that precedes the declaration of the member. Beispiel:For example

class A
{
    void F() {
        i = 1;
    }

    int i = 0;
}

Hier ist es gültig für, auf F den verwiesen i wird, bevor er deklariert wird.Here, it is valid for F to refer to i before it is declared.

Innerhalb des Gültigkeits Bereichs einer lokalen Variablen ist dies ein Kompilierzeitfehler, der auf die lokale Variable in einer Textposition verweist, die dem local_variable_declarator der lokalen Variablen vorangestellt ist.Within the scope of a local variable, it is a compile-time error to refer to the local variable in a textual position that precedes the local_variable_declarator of the local variable. Beispiel:For example

class A
{
    int i = 0;

    void F() {
        i = 1;                  // Error, use precedes declaration
        int i;
        i = 2;
    }

    void G() {
        int j = (j = 1);        // Valid
    }

    void H() {
        int a = 1, b = ++a;    // Valid
    }
}

In der F obigen Methode verweist die erste Zuweisung zu i speziell nicht auf das Feld, das im äußeren Gültigkeitsbereich deklariert wurde.In the F method above, the first assignment to i specifically does not refer to the field declared in the outer scope. Stattdessen verweist Sie auf die lokale Variable und führt zu einem Kompilierzeitfehler, da Sie sich textumal der Deklaration der Variablen vorangestellt ist.Rather, it refers to the local variable and it results in a compile-time error because it textually precedes the declaration of the variable. In der- G Methode ist die Verwendung von j im Initialisierer für die Deklaration von j gültig, da die Verwendung dem local_variable_declarator nicht vorangestellt ist.In the G method, the use of j in the initializer for the declaration of j is valid because the use does not precede the local_variable_declarator. In der- H Methode verweist eine nachfolgende local_variable_declarator ordnungsgemäß auf eine lokale Variable, die in einem früheren local_variable_declarator innerhalb desselben local_variable_declaration deklariert wurde.In the H method, a subsequent local_variable_declarator correctly refers to a local variable declared in an earlier local_variable_declarator within the same local_variable_declaration.

Die Bereichs Regeln für lokale Variablen dienen dazu, sicherzustellen, dass die Bedeutung eines Namens, der in einem Ausdrucks Kontext verwendet wird, innerhalb eines-Blocks immer identisch ist.The scoping rules for local variables are designed to guarantee that the meaning of a name used in an expression context is always the same within a block. Wenn der Gültigkeitsbereich einer lokalen Variablen nur von der Deklaration bis zum Ende des Blocks erweitert werden soll, wird im obigen Beispiel die erste Zuweisung der Instanzvariablen zugewiesen, und die zweite Zuweisung würde der lokalen Variablen zugewiesen, was möglicherweise zu Kompilier Zeitfehlern führt, wenn die Anweisungen des Blocks später neu angeordnet werden.If the scope of a local variable were to extend only from its declaration to the end of the block, then in the example above, the first assignment would assign to the instance variable and the second assignment would assign to the local variable, possibly leading to compile-time errors if the statements of the block were later to be rearranged.

Die Bedeutung eines Namens innerhalb eines-Blocks kann sich je nach Kontext unterscheiden, in dem der Name verwendet wird.The meaning of a name within a block may differ based on the context in which the name is used. Im BeispielIn the example

using System;

class A {}

class Test
{
    static void Main() {
        string A = "hello, world";
        string s = A;                            // expression context

        Type t = typeof(A);                      // type context

        Console.WriteLine(s);                    // writes "hello, world"
        Console.WriteLine(t);                    // writes "A"
    }
}

der Name A wird in einem Ausdrucks Kontext verwendet, um auf die lokale Variable A und in einem typkontext zu verweisen, um auf die Klasse zu verweisen A .the name A is used in an expression context to refer to the local variable A and in a type context to refer to the class A.

Namens ausblendenName hiding

Der Gültigkeitsbereich einer Entität umfasst in der Regel mehr Programmtext als der Deklarations Bereich der Entität.The scope of an entity typically encompasses more program text than the declaration space of the entity. Der Gültigkeitsbereich einer Entität kann insbesondere Deklarationen enthalten, die neue Deklarations Bereiche mit Entitäten mit demselben Namen enthalten.In particular, the scope of an entity may include declarations that introduce new declaration spaces containing entities of the same name. Diese Deklarationen bewirken, dass die ursprüngliche Entität *Hidden _ wird.Such declarations cause the original entity to become *hidden _. Umgekehrt wird eine Entität als _ sichtbar* bezeichnet, wenn Sie nicht ausgeblendet ist.Conversely, an entity is said to be _ visible* when it is not hidden.

Das Ausblenden von Namen tritt auf, wenn sich Bereiche überlappenName hiding occurs when scopes overlap through nesting and when scopes overlap through inheritance. Die Merkmale der beiden Arten von ausblenden werden in den folgenden Abschnitten beschrieben.The characteristics of the two types of hiding are described in the following sections.

Ausblenden durch SchachtelungHiding through nesting

Der Name, der durch Schachtelung ausgeblendet wird, kann als Ergebnis der Schachtelung von Namespaces oder Typen innerhalb von Namespaces auftreten, als Ergebnis der Schachtelung von Typen in Klassen oder Strukturen, und als Ergebnis von Parameter-und lokalen Variablen Deklarationen.Name hiding through nesting can occur as a result of nesting namespaces or types within namespaces, as a result of nesting types within classes or structs, and as a result of parameter and local variable declarations.

Im BeispielIn the example

class A
{
    int i = 0;

    void F() {
        int i = 1;
    }

    void G() {
        i = 1;
    }
}

innerhalb der- F Methode wird die Instanzvariable i von der lokalen Variablen ausgeblendet i , aber innerhalb der- G Methode i verweist immer noch auf die-Instanzvariable.within the F method, the instance variable i is hidden by the local variable i, but within the G method, i still refers to the instance variable.

Wenn ein Name in einem inneren Gültigkeitsbereich einen Namen in einem äußeren Gültigkeitsbereich verbirgt, werden alle überladenen Vorkommen dieses Namens ausgeblendet.When a name in an inner scope hides a name in an outer scope, it hides all overloaded occurrences of that name. Im BeispielIn the example

class Outer
{
    static void F(int i) {}

    static void F(string s) {}

    class Inner
    {
        void G() {
            F(1);              // Invokes Outer.Inner.F
            F("Hello");        // Error
        }

        static void F(long l) {}
    }
}

der Aufruf F(1) Ruft den F in deklarierten auf, Inner da alle äußeren Vorkommen von F durch die innere Deklaration ausgeblendet werden.the call F(1) invokes the F declared in Inner because all outer occurrences of F are hidden by the inner declaration. Aus demselben Grund führt der Aufruf zu F("Hello") einem Kompilierzeitfehler.For the same reason, the call F("Hello") results in a compile-time error.

Ausblenden durch VererbungHiding through inheritance

Das Ausblenden des Namens durch Vererbung tritt auf, wenn Klassen oder Strukturen Namen, die von Basisklassen geerbt wurden, neu deklarieren.Name hiding through inheritance occurs when classes or structs redeclare names that were inherited from base classes. Diese Art von namens ausblenden hat eine der folgenden Formen:This type of name hiding takes one of the following forms:

  • Eine Konstante, ein Feld, eine Eigenschaft, ein Ereignis oder ein Typ, die in einer Klasse oder Struktur eingeführt wurde, verbergen alle Basisklassenmember mit demselben Namen.A constant, field, property, event, or type introduced in a class or struct hides all base class members with the same name.
  • Eine Methode, die in einer Klasse oder Struktur eingeführt wurde, verbirgt alle nicht-Method-Basisklassenmember mit demselben Namen und alle Basisklassen Methoden mit der gleichen Signatur (Methodenname und Parameter Anzahl, Modifizierer und Typen).A method introduced in a class or struct hides all non-method base class members with the same name, and all base class methods with the same signature (method name and parameter count, modifiers, and types).
  • Ein Indexer, der in einer Klasse oder Struktur eingeführt wurde, verbirgt alle Basisklassenindexer mit der gleichen Signatur (Parameter Anzahl und-Typen).An indexer introduced in a class or struct hides all base class indexers with the same signature (parameter count and types).

Die Regeln für Operator Deklarationen (Operatoren) machen es für eine abgeleitete Klasse unmöglich, einen Operator mit derselben Signatur wie ein Operator in einer Basisklasse zu deklarieren.The rules governing operator declarations (Operators) make it impossible for a derived class to declare an operator with the same signature as an operator in a base class. Folglich verbergen Operatoren nie eine andere.Thus, operators never hide one another.

Im Gegensatz zum Ausblenden eines Namens aus einem äußeren Gültigkeitsbereich bewirkt das Ausblenden eines zugänglichen namens aus einem geerbten Bereich, dass eine Warnung ausgegeben wird.Contrary to hiding a name from an outer scope, hiding an accessible name from an inherited scope causes a warning to be reported. Im BeispielIn the example

class Base
{
    public void F() {}
}

class Derived: Base
{
    public void F() {}        // Warning, hiding an inherited name
}

die Deklaration von F in Derived bewirkt, dass eine Warnung gemeldet wird.the declaration of F in Derived causes a warning to be reported. Das Ausblenden eines geerbten Namens ist kein Fehler, da dies die getrennte Weiterentwicklung von Basisklassen ausschließen würde.Hiding an inherited name is specifically not an error, since that would preclude separate evolution of base classes. Die obige Situation könnte z. b. eintreten, weil eine neuere Version von Base eine Methode eingeführt hat F , die in einer früheren Version der Klasse nicht vorhanden war.For example, the above situation might have come about because a later version of Base introduced an F method that wasn't present in an earlier version of the class. Hätte die obige Situation einen Fehler verursacht, kann jede Änderung, die an einer Basisklasse in einer separat versionierten Klassenbibliothek vorgenommen wurde, möglicherweise dazu führen, dass abgeleitete Klassen ungültig werden.Had the above situation been an error, then any change made to a base class in a separately versioned class library could potentially cause derived classes to become invalid.

Die Warnung, die durch das Ausblenden eines geerbten Namens verursacht wurde, kann mithilfe des- new Modifizierers entfernt werden:The warning caused by hiding an inherited name can be eliminated through use of the new modifier:

class Base
{
    public void F() {}
}

class Derived: Base
{
    new public void F() {}
}

Der new -Modifizierer gibt an, dass der F in Derived "New" ist, und dass er tatsächlich dazu gedacht ist, den geerbten Member auszublenden.The new modifier indicates that the F in Derived is "new", and that it is indeed intended to hide the inherited member.

Eine Deklaration eines neuen Members verbirgt einen geerbten Member nur innerhalb des Gültigkeits Bereichs des neuen Members.A declaration of a new member hides an inherited member only within the scope of the new member.

class Base
{
    public static void F() {}
}

class Derived: Base
{
    new private static void F() {}    // Hides Base.F in Derived only
}

class MoreDerived: Derived
{
    static void G() { F(); }          // Invokes Base.F
}

Im obigen Beispiel blendet die Deklaration von F in Derived den F aus, der von geerbt wurde Base , aber da der neue F in Derived privaten Zugriff hat, wird sein Bereich nicht auf erweitert MoreDerived .In the example above, the declaration of F in Derived hides the F that was inherited from Base, but since the new F in Derived has private access, its scope does not extend to MoreDerived. Daher ist der Aufruf F() in MoreDerived.G gültig und wird aufgerufen Base.F .Thus, the call F() in MoreDerived.G is valid and will invoke Base.F.

Namespace and type names (Namespace- und Typnamen)Namespace and type names

Mehrere Kontexte in einem c#-Programm erfordern, dass ein namespace_name oder eine TYPE_NAME angegeben wird.Several contexts in a C# program require a namespace_name or a type_name to be specified.

namespace_name
    : namespace_or_type_name
    ;

type_name
    : namespace_or_type_name
    ;

namespace_or_type_name
    : identifier type_argument_list?
    | namespace_or_type_name '.' identifier type_argument_list?
    | qualified_alias_member
    ;

Eine namespace_name ist eine namespace_or_type_name , die auf einen Namespace verweist.A namespace_name is a namespace_or_type_name that refers to a namespace. Nach der Auflösung, wie unten beschrieben, muss die namespace_or_type_name eines namespace_name auf einen Namespace verweisen, andernfalls tritt ein Kompilierzeitfehler auf.Following resolution as described below, the namespace_or_type_name of a namespace_name must refer to a namespace, or otherwise a compile-time error occurs. In einem namespace_name können keine Typargumente (Typargumente) vorhanden sein (nur Typen können Typargumente aufweisen).No type arguments (Type arguments) can be present in a namespace_name (only types can have type arguments).

Ein TYPE_NAME ist eine namespace_or_type_name , die auf einen Typ verweist.A type_name is a namespace_or_type_name that refers to a type. Nach der Auflösung, wie unten beschrieben, muss die namespace_or_type_name eines TYPE_NAME auf einen Typ verweisen, andernfalls tritt ein Kompilierzeitfehler auf.Following resolution as described below, the namespace_or_type_name of a type_name must refer to a type, or otherwise a compile-time error occurs.

Wenn die namespace_or_type_name ein Qualified-Alias-Member ist, wird ihre Bedeutung wie in Namespacealias-Qualifizierernbeschrieben beschrieben.If the namespace_or_type_name is a qualified-alias-member its meaning is as described in Namespace alias qualifiers. Andernfalls hat eine namespace_or_type_name eine von vier Formen:Otherwise, a namespace_or_type_name has one of four forms:

  • I
  • I<A1, ..., Ak>
  • N.I
  • N.I<A1, ..., Ak>

Wenn I ein einzelner Bezeichner ist, N ist ein namespace_or_type_name und <A1, ..., Ak> ein optionaler type_argument_list.where I is a single identifier, N is a namespace_or_type_name and <A1, ..., Ak> is an optional type_argument_list. Wenn keine type_argument_list angegeben ist, sollten k Sie den Wert 0 (null) angeben.When no type_argument_list is specified, consider k to be zero.

Die Bedeutung eines namespace_or_type_name wird wie folgt bestimmt:The meaning of a namespace_or_type_name is determined as follows:

  • Wenn die namespace_or_type_name das Formular oder das folgende Format hat I I<A1, ..., Ak> :If the namespace_or_type_name is of the form I or of the form I<A1, ..., Ak>:
    • Wenn K 0 (null) ist und die namespace_or_type_name in einer generischen Methoden Deklaration (Methoden) enthalten ist und diese Deklaration einen Typparameter (Typparameter) mit dem Namen enthält  I , verweist der namespace_or_type_name auf diesen Typparameter.If K is zero and the namespace_or_type_name appears within a generic method declaration (Methods) and if that declaration includes a type parameter (Type parameters) with name I, then the namespace_or_type_name refers to that type parameter.
    • Andernfalls, wenn das namespace_or_type_name in einer Typdeklaration angezeigt wird, dann für jeden Instanztyp  T (der Instanztyp), beginnend mit dem Instanztyp dieser Typdeklaration und mit dem Instanztyp jeder einschließenden Klasse oder Struktur Deklaration (sofern vorhanden):Otherwise, if the namespace_or_type_name appears within a type declaration, then for each instance type T (The instance type), starting with the instance type of that type declaration and continuing with the instance type of each enclosing class or struct declaration (if any):
      • Wenn K 0 (null) ist und die Deklaration von T einen Typparameter mit dem Namen enthält  I , verweist der namespace_or_type_name auf diesen Typparameter.If K is zero and the declaration of T includes a type parameter with name I, then the namespace_or_type_name refers to that type parameter.
      • Andernfalls T  I K   verweist der namespace_or_type_name auf den Typ, der mit den angegebenen Typargumenten erstellt wurde, wenn die namespace_or_type_name im Text der Typdeklaration angezeigt wird und oder einer der zugehörigen Basis Typen einen geschachtelten zugänglichen Typ mit den Parametern "Name" und "Type" enthält.Otherwise, if the namespace_or_type_name appears within the body of the type declaration, and T or any of its base types contain a nested accessible type having name I and K type parameters, then the namespace_or_type_name refers to that type constructed with the given type arguments. Wenn mehr als ein solcher Typ vorhanden ist, wird der in einem stärker abgeleiteten Typ deklarierte Typ ausgewählt.If there is more than one such type, the type declared within the more derived type is selected. Beachten Sie, dass nicht-Typmember (Konstanten, Felder, Methoden, Eigenschaften, Indexer, Operatoren, Instanzkonstruktoren, Dekonstruktoren und statische Konstruktoren) und Typmember mit einer anderen Anzahl von Typparametern ignoriert werden, wenn die Bedeutung der namespace_or_type_name bestimmt wird.Note that non-type members (constants, fields, methods, properties, indexers, operators, instance constructors, destructors, and static constructors) and type members with a different number of type parameters are ignored when determining the meaning of the namespace_or_type_name.
    • Wenn die vorherigen Schritte nicht erfolgreich waren, wird für jeden Namespace  N , beginnend mit dem Namespace, in dem der namespace_or_type_name auftritt, der Fortschritt mit jedem einschließenden Namespace (sofern vorhanden) und mit dem globalen Namespace eine Auswertung der folgenden Schritte ausgeführt, bis eine Entität gefunden wird:If the previous steps were unsuccessful then, for each namespace N, starting with the namespace in which the namespace_or_type_name occurs, continuing with each enclosing namespace (if any), and ending with the global namespace, the following steps are evaluated until an entity is located:
      • Wenn K 0 (null) ist und I der Name eines Namespace in ist  N , dann gilt Folgendes:If K is zero and I is the name of a namespace in N, then:
        • Wenn der Speicherort, an dem der namespace_or_type_name auftritt, von einer Namespace Deklaration für eingeschlossen ist N und die Namespace Deklaration eine extern_alias_directive oder using_alias_directive enthält, die den Namen  I einem Namespace oder Typ zuordnet, ist die namespace_or_type_name mehrdeutig, und es tritt ein Kompilierungsfehler auf.If the location where the namespace_or_type_name occurs is enclosed by a namespace declaration for N and the namespace declaration contains an extern_alias_directive or using_alias_directive that associates the name I with a namespace or type, then the namespace_or_type_name is ambiguous and a compile-time error occurs.
        • Andernfalls verweist der namespace_or_type_name auf den Namespace mit dem Namen I in N .Otherwise, the namespace_or_type_name refers to the namespace named I in N.
      • Wenn andernfalls einen zugreif baren N Typ mit den Parametern "Name" und "Type" enthält  I K   , dann:Otherwise, if N contains an accessible type having name I and K type parameters, then:
        • Wenn K 0 (null) ist und die Position, an der die namespace_or_type_name auftritt, von einer Namespace Deklaration für eingeschlossen wird N und die Namespace Deklaration eine extern_alias_directive oder using_alias_directive enthält, die den Namen  I einem Namespace oder Typ zuordnet, ist die namespace_or_type_name mehrdeutig und ein Kompilierzeitfehler aufgetreten.If K is zero and the location where the namespace_or_type_name occurs is enclosed by a namespace declaration for N and the namespace declaration contains an extern_alias_directive or using_alias_directive that associates the name I with a namespace or type, then the namespace_or_type_name is ambiguous and a compile-time error occurs.
        • Andernfalls verweist der namespace_or_type_name auf den Typ, der mit den angegebenen Typargumenten erstellt wurde.Otherwise, the namespace_or_type_name refers to the type constructed with the given type arguments.
      • Andernfalls ist der Speicherort, an dem der namespace_or_type_name auftritt, von einer Namespace Deklaration für Folgendes eingeschlossen N :Otherwise, if the location where the namespace_or_type_name occurs is enclosed by a namespace declaration for N:
        • Wenn K 0 (null) ist und die-Namespace Deklaration eine extern_alias_directive oder using_alias_directive enthält, die den Namen  I einem importierten Namespace oder Typ zuordnet, verweist der namespace_or_type_name auf diesen Namespace oder Typ.If K is zero and the namespace declaration contains an extern_alias_directive or using_alias_directive that associates the name I with an imported namespace or type, then the namespace_or_type_name refers to that namespace or type.
        • Wenn die von den using_namespace_directive s und using_alias_directive s der Namespace Deklaration importierten Namespaces und Typdeklarationen genau einen zugreif baren Typ aufweisen, der über die Parameter "Name" und "Type" verfügt  I K   , verweist der namespace_or_type_name auf diesen Typ, der mit den angegebenen Typargumenten erstellt wurde.Otherwise, if the namespaces and type declarations imported by the using_namespace_directive s and using_alias_directive s of the namespace declaration contain exactly one accessible type having name I and K type parameters, then the namespace_or_type_name refers to that type constructed with the given type arguments.
        • Wenn die Namespaces und Typdeklarationen, die von den using_namespace_directive s und using_alias_directive s der Namespace Deklaration importiert werden, mehr als einen zugreif baren Typ aufweisen  I , der über namens-und K   Typparameter verfügt, ist die namespace_or_type_name mehrdeutig, und es tritt ein Fehler auf.Otherwise, if the namespaces and type declarations imported by the using_namespace_directive s and using_alias_directive s of the namespace declaration contain more than one accessible type having name I and K type parameters, then the namespace_or_type_name is ambiguous and an error occurs.
    • Andernfalls ist der namespace_or_type_name nicht definiert, und es tritt ein Kompilierzeitfehler auf.Otherwise, the namespace_or_type_name is undefined and a compile-time error occurs.
  • Andernfalls hat der namespace_or_type_name das Format N.I oder das Formular N.I<A1, ..., Ak> .Otherwise, the namespace_or_type_name is of the form N.I or of the form N.I<A1, ..., Ak>. N wird zuerst als namespace_or_type_name aufgelöst.N is first resolved as a namespace_or_type_name. Wenn die Auflösung von N nicht erfolgreich ist, tritt ein Kompilierzeitfehler auf.If the resolution of N is not successful, a compile-time error occurs. Andernfalls N.I wird oder N.I<A1, ..., Ak> wie folgt aufgelöst:Otherwise, N.I or N.I<A1, ..., Ak> is resolved as follows:
    • Wenn K 0 (null) ist und N auf einen Namespace verweist und N einen schsted Namespace mit dem Namen enthält I , verweist der namespace_or_type_name auf diesen schsted Namespace.If K is zero and N refers to a namespace and N contains a nested namespace with name I, then the namespace_or_type_name refers to that nested namespace.
    • Wenn N auf einen Namespace verweist und einen zugreif baren N Typ mit den Parametern "Name" und "Type" enthält  I K   , verweist der namespace_or_type_name auf diesen Typ, der mit den angegebenen Typargumenten erstellt wurde.Otherwise, if N refers to a namespace and N contains an accessible type having name I and K type parameters, then the namespace_or_type_name refers to that type constructed with the given type arguments.
    • Wenn sich andernfalls N auf eine (möglicherweise konstruiertes) Klasse oder einen Strukturtyp bezieht und N oder eine der zugehörigen Basisklassen einen für den nsted Typ zugänglichen Typ  I K   mit den Parametern Name und Type enthält, verweist der namespace_or_type_name auf diesen Typ, der mit den angegebenen Typargumenten erstellt wurde.Otherwise, if N refers to a (possibly constructed) class or struct type and N or any of its base classes contain a nested accessible type having name I and K type parameters, then the namespace_or_type_name refers to that type constructed with the given type arguments. Wenn mehr als ein solcher Typ vorhanden ist, wird der in einem stärker abgeleiteten Typ deklarierte Typ ausgewählt.If there is more than one such type, the type declared within the more derived type is selected. Beachten Sie Folgendes: Wenn die Bedeutung von N.I als Teil der Auflösung der Basisklassen Spezifikation von bestimmt wird, N gilt die direkte Basisklasse von als N Object (Basisklassen).Note that if the meaning of N.I is being determined as part of resolving the base class specification of N then the direct base class of N is considered to be object (Base classes).
    • Andernfalls N.I ist ein ungültiger namespace_or_type_name, und es tritt ein Kompilierzeitfehler auf.Otherwise, N.I is an invalid namespace_or_type_name, and a compile-time error occurs.

Ein namespace_or_type_name darf nur dann auf eine statische Klasse (statische Klassen) verweisen, wennA namespace_or_type_name is permitted to reference a static class (Static classes) only if

  • Der namespace_or_type_name ist T ein namespace_or_type_name des Formulars. T.IThe namespace_or_type_name is the T in a namespace_or_type_name of the form T.I, or
  • Der namespace_or_type_name ist das T in einem typeof_expression (Argument Listen1) im Formular typeof(T) .The namespace_or_type_name is the T in a typeof_expression (Argument lists1) of the form typeof(T).

Vollqualifizierte NamenFully qualified names

Jeder Namespace und Typ verfügt über einen voll qualifizierten Namen, der den Namespace oder den Typ unter allen anderen eindeutig identifiziert.Every namespace and type has a fully qualified name, which uniquely identifies the namespace or type amongst all others. Der voll qualifizierte Name eines Namespaces oder Typs N wird wie folgt bestimmt:The fully qualified name of a namespace or type N is determined as follows:

  • Wenn N ein Member des globalen Namespace ist, lautet der voll qualifizierte Name N .If N is a member of the global namespace, its fully qualified name is N.
  • Andernfalls lautet der voll qualifizierte Name S.N , wobei S der voll qualifizierte Name des Namespace oder Typs ist, in dem N deklariert wird.Otherwise, its fully qualified name is S.N, where S is the fully qualified name of the namespace or type in which N is declared.

Der voll qualifizierte Name von N ist also der vollständige hierarchische Pfad der Bezeichner, die zu N beginnen, beginnend mit dem globalen Namespace.In other words, the fully qualified name of N is the complete hierarchical path of identifiers that lead to N, starting from the global namespace. Da jeder Member eines Namespaces oder Typs einen eindeutigen Namen haben muss, folgt der voll qualifizierte Name eines Namespace oder Typs immer eindeutig.Because every member of a namespace or type must have a unique name, it follows that the fully qualified name of a namespace or type is always unique.

Das folgende Beispiel zeigt mehrere Namespace-und Typdeklarationen zusammen mit den zugehörigen voll qualifizierten Namen.The example below shows several namespace and type declarations along with their associated fully qualified names.

class A {}                // A

namespace X               // X
{
    class B               // X.B
    {
        class C {}        // X.B.C
    }

    namespace Y           // X.Y
    {
        class D {}        // X.Y.D
    }
}

namespace X.Y             // X.Y
{
    class E {}            // X.Y.E
}

Automatische SpeicherverwaltungAutomatic memory management

C# verwendet die automatische Speicherverwaltung, sodass Entwickler den von Objekten belegten Arbeitsspeicher manuell zuordnen und freigeben können.C# employs automatic memory management, which frees developers from manually allocating and freeing the memory occupied by objects. Automatische Speicher Verwaltungsrichtlinien werden von einem Garbage Collector implementiert.Automatic memory management policies are implemented by a garbage collector. Der Lebenszyklus der Speicherverwaltung eines Objekts lautet wie folgt:The memory management life cycle of an object is as follows:

  1. Wenn das Objekt erstellt wird, wird Arbeitsspeicher zugeordnet, der Konstruktor wird ausgeführt, und das Objekt wird als Live-Objekt betrachtet.When the object is created, memory is allocated for it, the constructor is run, and the object is considered live.
  2. Wenn auf das Objekt oder einen Teil davon nicht durch eine mögliche Fortsetzung der Ausführung zugegriffen werden kann, abgesehen von der Ausführung von dedededededektoren, wird das Objekt als nicht mehr verwendet und ist für die Zerstörung infrage.If the object, or any part of it, cannot be accessed by any possible continuation of execution, other than the running of destructors, the object is considered no longer in use, and it becomes eligible for destruction. Der c#-Compiler und der Garbage Collector können Code analysieren, um zu bestimmen, welche Verweise auf ein Objekt in Zukunft verwendet werden können.The C# compiler and the garbage collector may choose to analyze code to determine which references to an object may be used in the future. Wenn beispielsweise eine lokale Variable, die sich im Gültigkeitsbereich befindet, der einzige vorhandene Verweis auf ein Objekt ist, aber auf diese lokale Variable in keiner möglichen Fortsetzung der Ausführung vom aktuellen Ausführungs Punkt in der Prozedur verwiesen wird, kann das Garbage Collector das Objekt nicht mehr in Gebrauch behandeln.For instance, if a local variable that is in scope is the only existing reference to an object, but that local variable is never referred to in any possible continuation of execution from the current execution point in the procedure, the garbage collector may (but is not required to) treat the object as no longer in use.
  3. Sobald das Objekt für die Zerstörung geeignet ist, wird zu einem späteren Zeitpunkt der Dekonstruktor (Dekonstruktoren) für das Objekt ausgeführt.Once the object is eligible for destruction, at some unspecified later time the destructor (Destructors) (if any) for the object is run. Unter normalen Umständen wird der debugtor für das Objekt nur einmal ausgeführt, obwohl Implementierungs spezifische APIs das Überschreiben dieses Verhaltens zulassen können.Under normal circumstances the destructor for the object is run once only, though implementation-specific APIs may allow this behavior to be overridden.
  4. Sobald der Dekonstruktor für ein Objekt ausgeführt wird, und der Zugriff auf das Objekt oder einen Teil davon durch eine mögliche Fortsetzung der Ausführung (einschließlich der Ausführung von Dekonstruktoren) nicht möglich ist, wird das Objekt als nicht zugänglich angesehen, und das Objekt wird für die Auflistung qualifiziert.Once the destructor for an object is run, if that object, or any part of it, cannot be accessed by any possible continuation of execution, including the running of destructors, the object is considered inaccessible and the object becomes eligible for collection.
  5. Schließlich gibt der Garbage Collector zu einem späteren Zeitpunkt, nachdem das Objekt für die Auflistung infrage kommt, den diesem Objekt zugeordneten Arbeitsspeicher frei.Finally, at some time after the object becomes eligible for collection, the garbage collector frees the memory associated with that object.

Der Garbage Collector verwaltet Informationen zur Objekt Verwendung und verwendet diese Informationen, um Entscheidungen hinsichtlich der Speicherverwaltung zu treffen, z. b. wo im Arbeitsspeicher ein neu erstelltes Objekt zu finden ist, wann ein Objekt verschoben werden soll und wann ein Objekt nicht mehr verwendet wird oder nicht.The garbage collector maintains information about object usage, and uses this information to make memory management decisions, such as where in memory to locate a newly created object, when to relocate an object, and when an object is no longer in use or inaccessible.

Wie andere Sprachen, die voraussetzen, dass ein Garbage Collector vorhanden ist, wurde c# so entworfen, dass die Garbage Collector eine Vielzahl von Richtlinien für die Speicherverwaltung implementieren kann.Like other languages that assume the existence of a garbage collector, C# is designed so that the garbage collector may implement a wide range of memory management policies. Beispielsweise ist es für c# nicht erforderlich, dass Dekonstruktoren ausgeführt werden oder dass Objekte gesammelt werden, sobald Sie qualifiziert sind oder dass Dekonstruktoren in einer bestimmten Reihenfolge oder in einem bestimmten Thread ausgeführt werden.For instance, C# does not require that destructors be run or that objects be collected as soon as they are eligible, or that destructors be run in any particular order, or on any particular thread.

Das Verhalten des Garbage Collector kann in gewissem Maße über statische Methoden in der-Klasse gesteuert werden System.GC .The behavior of the garbage collector can be controlled, to some degree, via static methods on the class System.GC. Diese Klasse kann verwendet werden, um eine Auflistung anzufordern, Dekonstruktoren auszuführen (oder nicht ausgeführt) usw.This class can be used to request a collection to occur, destructors to be run (or not run), and so forth.

Da die Garbage Collector den Breitengrad der Entscheidung, wann Objekte gesammelt werden sollen, und die Ausführung von Debuggern unterstützt, kann eine konforme Implementierung eine Ausgabe ergeben, die sich von der im folgenden Code gezeigten unterscheidet.Since the garbage collector is allowed wide latitude in deciding when to collect objects and run destructors, a conforming implementation may produce output that differs from that shown by the following code. Das ProgrammThe program

using System;

class A
{
    ~A() {
        Console.WriteLine("Destruct instance of A");
    }
}

class B
{
    object Ref;

    public B(object o) {
        Ref = o;
    }

    ~B() {
        Console.WriteLine("Destruct instance of B");
    }
}

class Test
{
    static void Main() {
        B b = new B(new A());
        b = null;
        GC.Collect();
        GC.WaitForPendingFinalizers();
    }
}

erstellt eine Instanz der A -Klasse und eine Instanz der-Klasse B .creates an instance of class A and an instance of class B. Diese Objekte sind für Garbage Collection qualifiziert, wenn der b Wert der Variablen der Wert zugewiesen wird null . ab diesem Zeitpunkt ist es für keinen Benutzer geschriebenen Code unmöglich, darauf zuzugreifen.These objects become eligible for garbage collection when the variable b is assigned the value null, since after this time it is impossible for any user-written code to access them. Die Ausgabe kann entwederThe output could be either

Destruct instance of A
Destruct instance of B

oderor

Destruct instance of B
Destruct instance of A

Da in der Sprache keine Einschränkungen für die Reihenfolge auferlegt werden, in der Objekte in die Garbage Collection aufgenommen werden.because the language imposes no constraints on the order in which objects are garbage collected.

In einigen Fällen kann es wichtig sein, den Unterschied zwischen "berechtigte für Zerstörung" und "berechtigte Sammlung" zu unterscheiden.In subtle cases, the distinction between "eligible for destruction" and "eligible for collection" can be important. Beispiel:For example,

using System;

class A
{
    ~A() {
        Console.WriteLine("Destruct instance of A");
    }

    public void F() {
        Console.WriteLine("A.F");
        Test.RefA = this;
    }
}

class B
{
    public A Ref;

    ~B() {
        Console.WriteLine("Destruct instance of B");
        Ref.F();
    }
}

class Test
{
    public static A RefA;
    public static B RefB;

    static void Main() {
        RefB = new B();
        RefA = new A();
        RefB.Ref = RefA;
        RefB = null;
        RefA = null;

        // A and B now eligible for destruction
        GC.Collect();
        GC.WaitForPendingFinalizers();

        // B now eligible for collection, but A is not
        if (RefA != null)
            Console.WriteLine("RefA is not null");
    }
}

Wenn im obigen Programm der Garbage Collector den debugtor von A vor dem debugtor von ausführen möchte B , kann die Ausgabe dieses Programms wie folgt lauten:In the above program, if the garbage collector chooses to run the destructor of A before the destructor of B, then the output of this program might be:

Destruct instance of A
Destruct instance of B
A.F
RefA is not null

Beachten Sie, dass die-Instanz zwar A nicht in Gebrauch war und A der Dekonstruktor ausgeführt wurde, aber es ist weiterhin möglich, dass Methoden von A (in diesem Fall F ) von einem anderen Dekonstruktor aufgerufen werden.Note that although the instance of A was not in use and A's destructor was run, it is still possible for methods of A (in this case, F) to be called from another destructor. Beachten Sie außerdem, dass das Ausführen eines Dekonstruktors dazu führen kann, dass ein Objekt erneut aus dem Haupt-Programm verwendet werden kann.Also, note that running of a destructor may cause an object to become usable from the mainline program again. In diesem Fall hat der B Dekonstruktor von ausgeführt, dass eine Instanz von A , die zuvor nicht verwendet wurde, über den Live Verweis zugänglich ist Test.RefA .In this case, the running of B's destructor caused an instance of A that was previously not in use to become accessible from the live reference Test.RefA. Nach dem-Aufrufwert WaitForPendingFinalizers ist die Instanz von für die-Auflistung B qualifiziert, aber die-Instanz A ist aufgrund des-Verweises nicht Test.RefA .After the call to WaitForPendingFinalizers, the instance of B is eligible for collection, but the instance of A is not, because of the reference Test.RefA.

Um Verwirrung und unerwartetes Verhalten zu vermeiden, ist es im Allgemeinen eine gute Idee, dass debugtoren nur die Bereinigung für Daten ausführen, die in den eigenen Feldern Ihres Objekts gespeichert sind, und keine Aktionen für referenzierte Objekte oder statische Felder durchführen.To avoid confusion and unexpected behavior, it is generally a good idea for destructors to only perform cleanup on data stored in their object's own fields, and not to perform any actions on referenced objects or static fields.

Eine Alternative zur Verwendung von Dekonstruktoren besteht darin, dass eine Klasse die- System.IDisposable Schnittstelle implementiert.An alternative to using destructors is to let a class implement the System.IDisposable interface. Dadurch kann der Client des Objekts bestimmen, wann die Ressourcen des Objekts freigegeben werden sollen, in der Regel durch Zugriff auf das Objekt als Ressource in einer- using Anweisung (using-Anweisung).This allows the client of the object to determine when to release the resources of the object, typically by accessing the object as a resource in a using statement (The using statement).

AusführungsreihenfolgeExecution order

Die Ausführung eines c#-Programms wird so fortgesetzt, dass die Nebeneffekte der einzelnen ausführenden Threads an kritischen Ausführungs Punkten beibehalten werden.Execution of a C# program proceeds such that the side effects of each executing thread are preserved at critical execution points. Ein Nebeneffekt wird als Lese-oder Schreibvorgang eines flüchtigen Felds, eines Schreibzugriffs auf eine nicht flüchtige Variable, eines Schreibzugriffs auf eine externe Ressource und das Auslösen einer Ausnahme definiert.A side effect is defined as a read or write of a volatile field, a write to a non-volatile variable, a write to an external resource, and the throwing of an exception. Die kritischen Ausführungs Punkte, bei denen die Reihenfolge dieser Nebeneffekte beibehalten werden muss, sind Verweise auf flüchtige Felder (flüchtige Felder), lock Anweisungen (lock-Anweisung) und Thread Erstellung und-Beendigung.The critical execution points at which the order of these side effects must be preserved are references to volatile fields (Volatile fields), lock statements (The lock statement), and thread creation and termination. In der Ausführungsumgebung kann die Reihenfolge der Ausführung eines c#-Programms geändert werden, wobei die folgenden Einschränkungen gelten:The execution environment is free to change the order of execution of a C# program, subject to the following constraints:

  • Die Daten Abhängigkeit wird innerhalb eines Ausführungs Threads beibehalten.Data dependence is preserved within a thread of execution. Das heißt, der Wert jeder Variablen wird berechnet, als ob alle Anweisungen im Thread in der ursprünglichen Programm Reihenfolge ausgeführt wurden.That is, the value of each variable is computed as if all statements in the thread were executed in original program order.
  • Die Regeln für die Initialisierungs Reihenfolge werden beibehalten (Feld Initialisierung und Variableninitialisierer).Initialization ordering rules are preserved (Field initialization and Variable initializers).
  • Die Reihenfolge von Nebeneffekten wird in Bezug auf flüchtige Lese-und Schreibvorgänge (flüchtige Felder) beibehalten.The ordering of side effects is preserved with respect to volatile reads and writes (Volatile fields). Darüber hinaus muss die Ausführungsumgebung einen Teil eines Ausdrucks nicht auswerten, wenn er ableiten kann, dass der Wert des Ausdrucks nicht verwendet wird und keine erforderlichen Nebeneffekte erzeugt werden (einschließlich der durch Aufrufen einer Methode oder zugreifen auf ein flüchtiges Feld verursachten).Additionally, the execution environment need not evaluate part of an expression if it can deduce that that expression's value is not used and that no needed side effects are produced (including any caused by calling a method or accessing a volatile field). Wenn die Programmausführung durch ein asynchrones Ereignis (z. b. eine von einem anderen Thread ausgelöste Ausnahme) unterbrochen wird, ist es nicht sichergestellt, dass die wahrnehmbaren Nebeneffekte in der ursprünglichen Programm Reihenfolge sichtbar sind.When program execution is interrupted by an asynchronous event (such as an exception thrown by another thread), it is not guaranteed that the observable side effects are visible in the original program order.