EinführungIntroduction

C# (Aussprache „C Sharp“) ist eine einfache, moderne, objektorientierte und typsichere Programmiersprache.C# (pronounced "See Sharp") is a simple, modern, object-oriented, and type-safe programming language. C#hat seine Stämme in der c-Sprachen Familie und ist sofort mit c-, C++-und Java-Programmierern vertraut.C# has its roots in the C family of languages and will be immediately familiar to C, C++, and Java programmers. C#wird von ECMA International als ECMA-334- Standard und ISO/IEC als ISO/IEC 23270 -Standard standardisiert.C# is standardized by ECMA International as the ECMA-334 standard and by ISO/IEC as the ISO/IEC 23270 standard. Der C# Compiler für die .NET Framework von Microsoft ist eine konforme Implementierung beider Standards.Microsoft's C# compiler for the .NET Framework is a conforming implementation of both of these standards.

C# ist eine objektorientierte Sprache, umfasst allerdings auch Unterstützung für eine komponentenorientierte Programmierung.C# is an object-oriented language, but C# further includes support for component-oriented programming. Die Softwareentwicklung von heute beruht zunehmend auf Softwarekomponenten in Form von eigenständigen und selbstbeschreibenden Funktionspaketen.Contemporary software design increasingly relies on software components in the form of self-contained and self-describing packages of functionality. Wichtig bei solchen Komponenten ist, dass sie für ein Programmiermodell mit Eigenschaften, Methoden und Ereignissen stehen. Sie verfügen über Attribute, die deklarative Informationen zur Komponente bereitstellen, und lassen sich in ihre eigene Dokumentation integrieren.Key to such components is that they present a programming model with properties, methods, and events; they have attributes that provide declarative information about the component; and they incorporate their own documentation. C#stellt Sprachkonstrukte für die direkte Unterstützung dieser C# Konzepte bereit und stellt eine sehr natürliche Sprache dar, in der Softwarekomponenten erstellt und verwendet werden können.C# provides language constructs to directly support these concepts, making C# a very natural language in which to create and use software components.

Mehrere C#-Funktionen helfen beim Entwickeln stabiler und dauerhafter Anwendungen: Bei der automatischen Speicher Bereinigung wird der von nicht verwendeten Objekten belegte Speicher automatisch freigegeben. die Ausnahmebehandlung bietet eine strukturierte und erweiterbare Methode zur Fehlererkennung und-Wiederherstellung. und das typsichere Design der Sprache macht es nicht möglich, aus nicht initialisierten Variablen zu lesen, Arrays außerhalb ihrer Grenzen zu indizieren oder nicht überprüfte Typumwandlungen auszuführen.Several C# features aid in the construction of robust and durable applications: Garbage collection automatically reclaims memory occupied by unused objects; exception handling provides a structured and extensible approach to error detection and recovery; and the type-safe design of the language makes it impossible to read from uninitialized variables, to index arrays beyond their bounds, or to perform unchecked type casts.

C# verfügt über ein einheitliches Typsystem.C# has a unified type system. Alle C#-Typen, einschließlich primitiver Typen wie int und double, erben von einem einzelnen object-Stammtyp.All C# types, including primitive types such as int and double, inherit from a single root object type. Daher verwenden alle Typen einen Satz allgemeiner Vorgänge, und Werte eines beliebigen Typs können gespeichert, übertragen und konsistent ausgeführt werden.Thus, all types share a set of common operations, and values of any type can be stored, transported, and operated upon in a consistent manner. Darüber hinaus unterstützt C# benutzerdefinierte Verweistypen und Werttypen und ermöglicht so die dynamische Zuordnung von Objekten sowie die Inlinespeicherung einfacher Strukturen.Furthermore, C# supports both user-defined reference types and value types, allowing dynamic allocation of objects as well as in-line storage of lightweight structures.

Um sicherzustellen C# , dass Programme und Bibliotheken im Laufe C#der Zeit auf kompatible Weise weiterentwickelt werden können, wurde im Entwurf der Versions Kontrolle ein großer Schwerpunkt festgelegt.To ensure that C# programs and libraries can evolve over time in a compatible manner, much emphasis has been placed on versioning in C#'s design. Viele Programmiersprachen schenken diesem Problem wenig Beachtung, und in dieser Sprache geschriebene Programme stürzen daher häufiger als notwendig ab, wenn neuere Versionen abhängiger Bibliotheken eingeführt werden.Many programming languages pay little attention to this issue, and, as a result, programs written in those languages break more often than necessary when newer versions of dependent libraries are introduced. Aspekte des C#Entwurfs, die direkt von der Versionsverwaltung beeinflusst wurden, umfassen die virtual separaten override -und-Modifizierer, die Regeln für die Auflösung von Methoden Überladungen sowie die Unterstützung expliziter schnittstellenelementdeklarationen.Aspects of C#'s design that were directly influenced by versioning considerations include the separate virtual and override modifiers, the rules for method overload resolution, and support for explicit interface member declarations.

Im weiteren Verlauf dieses Kapitels werden die wesentlichen Features der- C# Sprache beschrieben.The rest of this chapter describes the essential features of the C# language. Obwohl in späteren Kapiteln Regeln und Ausnahmen ausführlich und manchmal auf mathematische Weise beschrieben werden, werden in diesem Kapitel Klarheit und Übersichtlichkeit auf Kosten der Vollständigkeit angestrebt.Although later chapters describe rules and exceptions in a detail-oriented and sometimes mathematical manner, this chapter strives for clarity and brevity at the expense of completeness. Die Absicht besteht darin, dem Reader eine Einführung in die Sprache bereitzustellen, die das Schreiben von frühen Programmen und das Lesen von späteren Kapiteln erleichtert.The intent is to provide the reader with an introduction to the language that will facilitate the writing of early programs and the reading of later chapters.

Hello WorldHello world

Das Programm „Hello, World“ wird für gewöhnlich zur Einführung einer Programmiersprache verwendet.The "Hello, World" program is traditionally used to introduce a programming language. Hier ist es in C#:Here it is in C#:

using System;

class Hello
{
    static void Main() {
        Console.WriteLine("Hello, World");
    }
}

C#-Quelldateien weisen in der Regel die Dateierweiterung .cs auf.C# source files typically have the file extension .cs. Wenn das Programm "Hello, World" in der Datei hello.csgespeichert ist, kann das Programm über die Befehlszeile mit dem Microsoft C# -Compiler kompiliert werden.Assuming that the "Hello, World" program is stored in the file hello.cs, the program can be compiled with the Microsoft C# compiler using the command line

csc hello.cs

die eine ausführbare Assembly mit hello.exedem Namen erzeugt.which produces an executable assembly named hello.exe. Die von dieser Anwendung beim Ausführen von erstellte Ausgabe istThe output produced by this application when it is run is

Hello, World

Das Programm „Hello, World“ wird mit einer using-Richtlinie gestartet, die auf den System-Namespace verweist.The "Hello, World" program starts with a using directive that references the System namespace. Namespaces bieten eine hierarchische Möglichkeit zum Organisieren von C#-Programmen und -Bibliotheken.Namespaces provide a hierarchical means of organizing C# programs and libraries. Namespaces enthalten Typen und andere Namespaces. Beispiel: Der System-Namespace enthält eine Reihe von Typen, wie etwa die Console-Klasse, auf die im Programm verwiesen wird, und eine Reihe anderer Namespaces, wie etwa IO und Collections.Namespaces contain types and other namespaces—for example, the System namespace contains a number of types, such as the Console class referenced in the program, and a number of other namespaces, such as IO and Collections. Eine using-Richtlinie, die auf einen bestimmten Namespace verweist, ermöglicht die nicht qualifizierte Nutzung der Typen, die Member dieses Namespace sind.A using directive that references a given namespace enables unqualified use of the types that are members of that namespace. Aufgrund der using-Direktive kann das Programm Console.WriteLine als Abkürzung für System.Console.WriteLine verwenden.Because of the using directive, the program can use Console.WriteLine as shorthand for System.Console.WriteLine.

Die Hello-Klasse, die vom Programm „Hello, World“ deklariert wird, verfügt über einen einzelnen Member: die Main-Methode.The Hello class declared by the "Hello, World" program has a single member, the method named Main. Die Main -Methode wird mit dem static -Modifizierer deklariert.The Main method is declared with the static modifier. Auch wenn Instanzmethoden mit dem Schlüsselwort this auf eine bestimmte einschließende Objektinstanz verweisen können, agieren statische Methoden ohne Verweis auf ein bestimmtes Objekt.While instance methods can reference a particular enclosing object instance using the keyword this, static methods operate without reference to a particular object. Gemäß der Konvention fungiert eine statische Methode mit der Bezeichnung Main als Einstiegspunkt eines Programms.By convention, a static method named Main serves as the entry point of a program.

Die Ausgabe des Programms wird anhand der WriteLine-Methode der Console-Klasse im System-Namespace generiert.The output of the program is produced by the WriteLine method of the Console class in the System namespace. Diese Klasse wird von den .NET Framework-Klassenbibliotheken bereitgestellt, die standardmäßig automatisch vom Microsoft C# -Compiler referenziert werden.This class is provided by the .NET Framework class libraries, which, by default, are automatically referenced by the Microsoft C# compiler. Beachten Sie C# , dass selbst über keine separate Lauf Zeit Bibliothek verfügt.Note that C# itself does not have a separate runtime library. Stattdessen ist der .NET Framework die Lauf Zeit Bibliothek von C#.Instead, the .NET Framework is the runtime library of C#.

ProgrammstrukturProgram structure

Die organisatorischen Schlüsselkonzepte in C# sind: Programme, Namespaces, Typen, Member und Assemblys.The key organizational concepts in C# are programs, namespaces, types, members, and assemblies. C#-Programme bestehen aus mindestens einer Quelldatei.C# programs consist of one or more source files. Programme deklarieren Typen, die Member enthalten, und können in Namespaces organisiert werden.Programs declare types, which contain members and can be organized into namespaces. Klassen und Schnittstellen sind Beispiele für Typen.Classes and interfaces are examples of types. Felder, Methoden, Eigenschaften und Ereignisse sind Beispiele für Member.Fields, methods, properties, and events are examples of members. Wenn C#-Programme kompiliert werden, werden sie physisch in Assemblys verpackt.When C# programs are compiled, they are physically packaged into assemblies. Assemblys verfügen in der .exe Regel .dllüber die Dateierweiterung oder, je nachdem, ob Sie Anwendungen oder Bibliothekenimplementieren.Assemblies typically have the file extension .exe or .dll, depending on whether they implement applications or libraries.

Das BeispielThe example

using System;

namespace Acme.Collections
{
    public class Stack
    {
        Entry top;

        public void Push(object data) {
            top = new Entry(top, data);
        }

        public object Pop() {
            if (top == null) throw new InvalidOperationException();
            object result = top.data;
            top = top.next;
            return result;
        }

        class Entry
        {
            public Entry next;
            public object data;
    
            public Entry(Entry next, object data) {
                this.next = next;
                this.data = data;
            }
        }
    }
}

deklariert eine Klasse mit Stack dem Namen in einem Acme.CollectionsNamespace mit dem Namen.declares a class named Stack in a namespace called Acme.Collections. Der vollqualifizierte Name dieser Klasse ist Acme.Collections.Stack.The fully qualified name of this class is Acme.Collections.Stack. Die Klasse enthält mehrere Member: ein Feld mit dem Namen top, zwei Methoden mit dem Namen Push und Pop sowie eine geschachtelte Klasse mit dem Namen Entry.The class contains several members: a field named top, two methods named Push and Pop, and a nested class named Entry. Die Entry-Klasse enthält weitere drei Member: ein Feld mit dem Namen next, ein Feld mit dem Namen data und einen Konstruktor.The Entry class further contains three members: a field named next, a field named data, and a constructor. Vorausgesetzt, dass der Quellcode des Beispiels in der Datei acme.cs gespeichert wird, kompiliert die BefehlszeileAssuming that the source code of the example is stored in the file acme.cs, the command line

csc /t:library acme.cs

das Beispiel als Bibliothek (Code ohne Main-Einstiegspunkt) und erstellt eine Assembly mit dem Namen acme.dll.compiles the example as a library (code without a Main entry point) and produces an assembly named acme.dll.

Assemblys enthalten ausführbaren Code in Form von Intermediate Language (IL)-Anweisungen und symbolische Informationen in Form von Metadaten.Assemblies contain executable code in the form of Intermediate Language (IL) instructions, and symbolic information in the form of metadata. Vor der Ausführung wird der IL-Code in einer Assembly automatisch durch den Just-in-Time-Compiler (JIT) der .NET Common Language Runtime in prozessorspezifischen Code konvertiert.Before it is executed, the IL code in an assembly is automatically converted to processor-specific code by the Just-In-Time (JIT) compiler of .NET Common Language Runtime.

Da eine Assembly eine selbstbeschreibende Funktionseinheit mit Code und Metadaten ist, besteht in C# keine Notwendigkeit für #include-Direktiven und Headerdateien.Because an assembly is a self-describing unit of functionality containing both code and metadata, there is no need for #include directives and header files in C#. Die öffentlichen Typen und Member, die in einer bestimmten Assembly enthalten sind, werden einfach durch Verweisen auf die Assembly beim Kompilieren des Programms in einem C#-Programm verfügbar gemacht.The public types and members contained in a particular assembly are made available in a C# program simply by referencing that assembly when compiling the program. Dieses Programm verwendet z.B. die Acme.Collections.Stack-Klasse aus der acme.dll-Assembly:For example, this program uses the Acme.Collections.Stack class from the acme.dll assembly:

using System;
using Acme.Collections;

class Test
{
    static void Main() {
        Stack s = new Stack();
        s.Push(1);
        s.Push(10);
        s.Push(100);
        Console.WriteLine(s.Pop());
        Console.WriteLine(s.Pop());
        Console.WriteLine(s.Pop());
    }
}

Wenn das Programm test.csin der Datei gespeichert wird, kann bei test.cs der Kompilierung acme.dll von auf die Assembly mit der- /r Option des Compilers verwiesen werden:If the program is stored in the file test.cs, when test.cs is compiled, the acme.dll assembly can be referenced using the compiler's /r option:

csc /r:acme.dll test.cs

So wird eine ausführbare Assembly mit dem Namen test.exe erstellt, die bei Ausführung folgende Ausgabe erzeugt:This creates an executable assembly named test.exe, which, when run, produces the output:

100
10
1

In C# kann der Quelltext eines Programms in verschiedenen Quelldateien gespeichert werden.C# permits the source text of a program to be stored in several source files. Bei der Kompilierung eines C#-Programms mit mehreren Dateien werden alle Quelldateien zusammen verarbeitet, und die Quelldateien können frei aufeinander verweisen – vom Konzept her ist es so, als seien alle Quelldateien vor der Verarbeitung in einer einzigen großen Datei verkettet worden.When a multi-file C# program is compiled, all of the source files are processed together, and the source files can freely reference each other—conceptually, it is as if all the source files were concatenated into one large file before being processed. Vorwärtsdeklarationen sind in C# nie erforderlich, da die Reihenfolge der Deklaration mit wenigen Ausnahmen unbedeutend ist.Forward declarations are never needed in C# because, with very few exceptions, declaration order is insignificant. C# beschränkt eine Quelldatei weder auf die Deklaration eines einzigen öffentlichen Typs, noch muss der Name der Quelldatei mit einem in der Quelldatei deklarierten Typ übereinstimmen.C# does not limit a source file to declaring only one public type nor does it require the name of the source file to match a type declared in the source file.

Typen und VariablenTypes and variables

Es gibt zwei Arten von Typen in C#: Werttypen und Verweistypen.There are two kinds of types in C#: value types and reference types. Variablen von Werttypen enthalten ihre Daten direkt, Variablen von Verweistypen speichern hingegen Verweise auf ihre Daten – letztere werden als Objekte bezeichnet.Variables of value types directly contain their data whereas variables of reference types store references to their data, the latter being known as objects. Mit Verweistypen können zwei Variablen auf das gleiche Objekt verweisen, und so können an einer Variablen durchgeführte Vorgänge das Objekt beeinflussen, auf das die andere Variable verweist.With reference types, it is possible for two variables to reference the same object and thus possible for operations on one variable to affect the object referenced by the other variable. Bei Werttypen besitzt jede Variable eine eigene Kopie der Daten, und auf eine Variable angewendete Vorgänge können die andere Variable nicht beeinflussen (außer im Fall von ref- und out-Parametervariablen).With value types, the variables each have their own copy of the data, and it is not possible for operations on one to affect the other (except in the case of ref and out parameter variables).

C#die Werttypen sind weiter unterteilt in einfache Typen, Enumerationstypen, Strukturtypenund Typen, C#die NULL-Werte zulassen, und die Verweis Typen sind weiter unterteilt in Klassentypen, Schnittstellentypen, Array Typenund Delegattypen.C#'s value types are further divided into simple types, enum types, struct types, and nullable types, and C#'s reference types are further divided into class types, interface types, array types, and delegate types.

In der folgenden Tabelle finden Sie eine C#Übersicht über das Typsystem.The following table provides an overview of C#'s type system.

KategorieCategory BeschreibungDescription
WerttypenValue types Einfache TypenSimple types Ganzzahlig mit Vorzeichen: sbyte, short, int,longSigned integral: sbyte, short, int, long
Ganzzahlig ohne Vorzeichen: byte, ushort, uint,ulongUnsigned integral: byte, ushort, uint, ulong
Unicode-Zeichen: charUnicode characters: char
IEEE-Gleitkomma: float, doubleIEEE floating point: float, double
Dezimalwert mit hoher Genauigkeit: decimalHigh-precision decimal: decimal
Boolesch: boolBoolean: bool
EnumerationstypenEnum types Benutzerdefinierte Typen der Form enum E {...}User-defined types of the form enum E {...}
StrukturtypenStruct types Benutzerdefinierte Typen der Form struct S {...}User-defined types of the form struct S {...}
Auf NULL festlegbare TypenNullable types Erweiterungen aller anderen Werttypen mit einem null-WertExtensions of all other value types with a null value
VerweistypenReference types KlassentypenClass types Ultimative Basisklasse aller anderen Typen:objectUltimate base class of all other types: object
Unicode-Zeichenfolgen: stringUnicode strings: string
Benutzerdefinierte Typen der Form class C {...}User-defined types of the form class C {...}
SchnittstellentypenInterface types Benutzerdefinierte Typen der Form interface I {...}User-defined types of the form interface I {...}
ArraytypenArray types Ein- und mehrdimensional, z.B. int[] undint[,]Single- and multi-dimensional, for example, int[] and int[,]
DelegattypenDelegate types Benutzerdefinierte Typen der Form, z. b.delegate int D(...)User-defined types of the form e.g. delegate int D(...)

Die acht Ganzzahltypen unterstützen 8-Bit-, 16-Bit, 32-Bit- und 64-Bit-Werte mit oder ohne Vorzeichen.The eight integral types provide support for 8-bit, 16-bit, 32-bit, and 64-bit values in signed or unsigned form.

Die zwei Gleit Komma Typen, float und double, werden mit den 32-Bit-Formaten für die einfache Genauigkeit und 64 Bit mit doppelter Genauigkeit mit doppelter 754 Genauigkeit dargestellt.The two floating point types, float and double, are represented using the 32-bit single-precision and 64-bit double-precision IEEE 754 formats.

Der decimal-Typ ist ein für Finanz-und Währungsberechnungen geeigneter 128-Bit-Datentyp.The decimal type is a 128-bit data type suitable for financial and monetary calculations.

C#der bool Typ wird verwendet, um boolesche Werte darzustellen – Werte, die true entweder falseoder sind.C#'s bool type is used to represent boolean values—values that are either true or false.

Zur Zeichen- und Zeichenfolgenverarbeitung in C# wird die Unicode-Codierung verwendet.Character and string processing in C# uses Unicode encoding. Der char-Typ stellt eine UTF-16-Codeeinheit dar und der string-Typ eine Folge von UTF-16-Codeeinheiten.The char type represents a UTF-16 code unit, and the string type represents a sequence of UTF-16 code units.

In der folgenden Tabelle C#sind die numerischen Typen zusammengefasst.The following table summarizes C#'s numeric types.

KategorieCategory BohrerBits TypType Bereich/GenauigkeitRange/Precision
Ganzzahliges VorzeichenSigned integral 88 sbyte -128... 127-128...127
1616 short -32768... 32, 767-32,768...32,767
3232 int -2147483648... 2, 147, 483, 647-2,147,483,648...2,147,483,647
6464 long -9.223.372.036.854.775.808... 9, 223, 372, 036, 854, 775, 807-9,223,372,036,854,775,808...9,223,372,036,854,775,807
Ganzzahlig ohne VorzeichenUnsigned integral 88 byte 0... 2550...255
1616 ushort 0... 65, 5350...65,535
3232 uint 0... 4, 294, 967, 2950...4,294,967,295
6464 ulong 0... 18, 446, 744, 073, 709, 551, 6150...18,446,744,073,709,551,615
GleitkommaFloating point 3232 float 1,5 × 10 ^ − 45 bis 3,4 × 10 ^ 38, 7-stellige Genauigkeit1.5 × 10^−45 to 3.4 × 10^38, 7-digit precision
6464 double 5,0 × 10 ^ − 324 bis 1,7 × 10 ^ 308, 15-stellige Genauigkeit5.0 × 10^−324 to 1.7 × 10^308, 15-digit precision
DecimalDecimal 128128 decimal 1,0 × 10 ^ − 28 bis 7,9 × 10 ^ 28, 28-stellige Genauigkeit1.0 × 10^−28 to 7.9 × 10^28, 28-digit precision

C#-Programme verwenden Typdeklarationen, um neue Typen zu erstellen.C# programs use type declarations to create new types. Eine Typdeklaration gibt den Namen und die Member des neuen Typs an.A type declaration specifies the name and the members of the new type. Fünf Kategorien C#von Typen sind benutzerdefinierbar: Klassentypen, Strukturtypen, Schnittstellentypen, Enumerationstypen und Delegattypen.Five of C#'s categories of types are user-definable: class types, struct types, interface types, enum types, and delegate types.

Ein Klassentyp definiert eine Datenstruktur, die Datenmember (Felder) und Funktionsmember (Methoden, Eigenschaften usw.) enthält.A class type defines a data structure that contains data members (fields) and function members (methods, properties, and others). Klassentypen unterstützen einzelne Vererbung und Polymorphie. Dies sind Mechanismen, durch die abgeleitete Klassen erweitert und Basisklassen spezialisiert werden können.Class types support single inheritance and polymorphism, mechanisms whereby derived classes can extend and specialize base classes.

Ein Strukturtyp ähnelt einem Klassentyp darin, dass er eine Struktur mit Datenmembern und Funktionsmembern darstellt.A struct type is similar to a class type in that it represents a structure with data members and function members. Im Unterschied zu Klassen sind Strukturen jedoch Werttypen und erfordern keine Heap Zuordnung.However, unlike classes, structs are value types and do not require heap allocation. Strukturtypen unterstützen keine benutzerdefinierte Vererbung, und alle Strukturtypen erben implizit vom Typ object.Struct types do not support user-specified inheritance, and all struct types implicitly inherit from type object.

Ein Schnittstellentyp definiert einen Vertrag als einen benannten Satz von öffentlichen Funktionsmembern.An interface type defines a contract as a named set of public function members. Eine Klasse oder Struktur, die eine Schnittstelle implementiert, muss Implementierungen der Funktionsmember der Schnittstelle bereitstellen.A class or struct that implements an interface must provide implementations of the interface's function members. Eine Schnittstelle kann von mehreren Basis Schnittstellen erben, und eine Klasse oder Struktur kann mehrere Schnittstellen implementieren.An interface may inherit from multiple base interfaces, and a class or struct may implement multiple interfaces.

Ein Delegattyp stellt Verweise auf Methoden mit einer bestimmten Parameterliste und einem Rückgabetyp dar.A delegate type represents references to methods with a particular parameter list and return type. Delegate ermöglichen die Behandlung von Methoden als Entitäten, die Variablen zugewiesen und als Parameter übergeben werden können.Delegates make it possible to treat methods as entities that can be assigned to variables and passed as parameters. Delegate ähneln dem Konzept von Funktionszeigern, die Sie in einigen anderen Sprachen finden. Im Gegensatz zu Funktionszeigern sind Delegate allerdings objektorientiert und typsicher.Delegates are similar to the concept of function pointers found in some other languages, but unlike function pointers, delegates are object-oriented and type-safe.

Klassen-, Struktur-, Schnittstellen-und Delegattypen unterstützen alle Generika, wobei Sie mit anderen Typen parametrisiert werden können.Class, struct, interface and delegate types all support generics, whereby they can be parameterized with other types.

Ein Enumerationstyp ist ein eindeutiger Typ mit benannten Konstanten.An enum type is a distinct type with named constants. Jeder Enumerationstyp verfügt über einen zugrunde liegenden Typ, bei dem es sich um einen der acht ganzzahligen Typen handeln muss.Every enum type has an underlying type, which must be one of the eight integral types. Der Satz von Werten eines Enumerationstyps ist mit dem Satz von Werten des zugrunde liegenden Typs identisch.The set of values of an enum type is the same as the set of values of the underlying type.

C# unterstützt ein- und mehrdimensionale Arrays beliebigen Typs.C# supports single- and multi-dimensional arrays of any type. Im Gegensatz zu den oben aufgeführten Typen müssen Arraytypen nicht deklariert werden, bevor sie verwendet werden können.Unlike the types listed above, array types do not have to be declared before they can be used. Stattdessen werden Arraytypen erstellt, indem hinter einen Typnamen eckige Klammern gesetzt werden.Instead, array types are constructed by following a type name with square brackets. Beispielsweise int[] ist ein eindimensionales Array von int, int[,] ist ein zweidimensionales Array von intund int[][] ist ein eindimensionales Array von eindimensionalen Arrays von int.For example, int[] is a single-dimensional array of int, int[,] is a two-dimensional array of int, and int[][] is a single-dimensional array of single-dimensional arrays of int.

Typen, die NULL-Werte zulassen, müssen auch nicht deklariert werden, bevor Sie verwendet werden können.Nullable types also do not have to be declared before they can be used. Für jeden Werttyp T , der keine NULL-Werte zulässt, gibt es T?einen entsprechenden Werte zulässt-Typ, nullder einen zusätzlichen Wert enthalten kann.For each non-nullable value type T there is a corresponding nullable type T?, which can hold an additional value null. Beispielsweise nullist ein Typ, der eine beliebige 32-Bit-Ganzzahl oder den Wert enthalten kann. int?For instance, int? is a type that can hold any 32 bit integer or the value null.

C#das Typsystem ist einheitlich, sodass ein Wert eines beliebigen Typs als Objekt behandelt werden kann.C#'s type system is unified such that a value of any type can be treated as an object. Jeder Typ in C# ist direkt oder indirekt vom object-Klassentyp abgeleitet, und object ist die ultimative Basisklasse aller Typen.Every type in C# directly or indirectly derives from the object class type, and object is the ultimate base class of all types. Werte von Verweistypen werden als Objekte behandelt, indem die Werte einfach als Typ object angezeigt werden.Values of reference types are treated as objects simply by viewing the values as type object. Werte von Werttypen werden als Objekte behandelt, indem Boxing -und Unboxing -Vorgänge durchgeführt werden.Values of value types are treated as objects by performing boxing and unboxing operations. Im folgenden Beispiel wird ein int-Wert in ein object und wieder in einen int-Wert konvertiert.In the following example, an int value is converted to object and back again to int.

using System;

class Test
{
    static void Main() {
        int i = 123;
        object o = i;          // Boxing
        int j = (int)o;        // Unboxing
    }
}

Wenn ein Wert eines Werttyps in den Typ objectkonvertiert wird, wird eine Objektinstanz, die auch als "Box" bezeichnet wird, zum Speichern des Werts zugeordnet, und der Wert wird in dieses Feld kopiert.When a value of a value type is converted to type object, an object instance, also called a "box," is allocated to hold the value, and the value is copied into that box. Wenn umgekehrt ein object Verweis in einen Werttyp umgewandelt wird, wird überprüft, ob das Objekt, auf das verwiesen wird, ein Feld des korrekten Werttyps ist, und wenn die Überprüfung erfolgreich ist, wird der Wert im Feld kopiert.Conversely, when an object reference is cast to a value type, a check is made that the referenced object is a box of the correct value type, and, if the check succeeds, the value in the box is copied out.

C#das vereinheitlichte Typsystem bedeutet, dass Werttypen "Bedarfs gesteuert" Objekte werden können.C#'s unified type system effectively means that value types can become objects "on demand." Aufgrund der Vereinheitlichung können Bibliotheken für allgemeine Zwecke, die den Typ object verwenden, sowohl mit Verweis- als auch Werttypen verwendet werden.Because of the unification, general-purpose libraries that use type object can be used with both reference types and value types.

Es gibt mehrere Arten von Variablen in C#, einschließlich Feldern, Arrayelementen, lokalen Variablen und Parametern.There are several kinds of variables in C#, including fields, array elements, local variables, and parameters. Variablen stellen Speicherorte dar, und jede Variable verfügt über einen Typ, der bestimmt, welche Werte in der Variablen gespeichert werden können, wie in der folgenden Tabelle dargestellt.Variables represent storage locations, and every variable has a type that determines what values can be stored in the variable, as shown by the following table.

Typ der VariablenType of Variable Möglicher InhaltPossible Contents
Nicht auf NULL festlegbarer WerttypNon-nullable value type Ein Wert genau dieses TypsA value of that exact type
Auf NULL festlegbarer WerttypNullable value type Ein NULL-Wert oder ein Wert dieses exakten Typs.A null value or a value of that exact type
object Ein NULL-Verweis, ein Verweis auf ein Objekt eines beliebigen Verweis Typs oder ein Verweis auf einen geboxten Wert eines beliebigen Werttyps.A null reference, a reference to an object of any reference type, or a reference to a boxed value of any value type
KlassentypClass type Ein NULL-Verweis, ein Verweis auf eine Instanz dieses Klassen Typs oder ein Verweis auf eine Instanz einer Klasse, die von diesem Klassentyp abgeleitet ist.A null reference, a reference to an instance of that class type, or a reference to an instance of a class derived from that class type
SchnittstellentypInterface type Ein NULL-Verweis, ein Verweis auf eine Instanz eines Klassen Typs, der diesen Schnittstellentyp implementiert, oder ein Verweis auf einen geboxten Wert eines Werttyps, der diesen Schnittstellentyp implementiert.A null reference, a reference to an instance of a class type that implements that interface type, or a reference to a boxed value of a value type that implements that interface type
ArraytypArray type Ein NULL-Verweis, ein Verweis auf eine Instanz dieses Array Typs oder ein Verweis auf eine Instanz eines kompatiblen Arraytyps.A null reference, a reference to an instance of that array type, or a reference to an instance of a compatible array type
DelegattypDelegate type Ein NULL-Verweis oder ein Verweis auf eine Instanz dieses Delegattyps.A null reference or a reference to an instance of that delegate type

AusdrückeExpressions

Ausdrücke bestehen aus Operanden und Operatoren.Expressions are constructed from operands and operators. Die Operatoren eines Ausdrucks geben an, welche Operationen auf die Operanden angewendet werden.The operators of an expression indicate which operations to apply to the operands. Beispiele für Operatoren sind +, -, *, / und new.Examples of operators include +, -, *, /, and new. Beispiele für Operanden sind Literale, Felder, lokale Variablen und Ausdrücke.Examples of operands include literals, fields, local variables, and expressions.

Wenn ein Ausdruck mehrere Operatoren enthält, bestimmt die Rangfolge der Operatoren die Reihenfolge, in der die einzelnen Operatoren ausgewertet werden.When an expression contains multiple operators, the precedence of the operators controls the order in which the individual operators are evaluated. Der Ausdruck x + y * z wird z.B. als x + (y * z) ausgewertet, da der *-Operator Vorrang vor dem +-Operator hat.For example, the expression x + y * z is evaluated as x + (y * z) because the * operator has higher precedence than the + operator.

Die meisten Operatoren können überladen werden.Most operators can be overloaded. Das Überladen von Operatoren ermöglicht die Angabe benutzerdefinierter Operatorimplementierungen für Vorgänge, in denen einer der Operanden oder beide einer benutzerdefinierten Klasse oder einem benutzerdefinierten Strukturtyp angehören.Operator overloading permits user-defined operator implementations to be specified for operations where one or both of the operands are of a user-defined class or struct type.

In der folgenden Tabelle C#sind die Operatoren zusammengefasst, wobei die Operator Kategorien in der Rangfolge von der höchsten zur niedrigsten aufgeführt sind.The following table summarizes C#'s operators, listing the operator categories in order of precedence from highest to lowest. Operatoren der gleichen Kategorie haben den gleichen Rang.Operators in the same category have equal precedence.

KategorieCategory expressionExpression BeschreibungDescription
PrimärPrimary x.m MemberzugriffMember access
x(...) Methoden- und DelegataufrufMethod and delegate invocation
x[...] Array- und IndexerzugriffArray and indexer access
x++ PostinkrementPost-increment
x-- PostdekrementPost-decrement
new T(...) Objekt- und DelegaterstellungObject and delegate creation
new T(...){...} Objekterstellung mit InitialisiererObject creation with initializer
new {...} Anonymer ObjektinitialisiererAnonymous object initializer
new T[...] ArrayerstellungArray creation
typeof(T) Abrufen von System.Type-Objekt für TObtain System.Type object for T
checked(x) Auswerten von Ausdrücken in geprüftem KontextEvaluate expression in checked context
unchecked(x) Auswerten von Ausdrücken in nicht geprüftem KontextEvaluate expression in unchecked context
default(T) Abrufen des Standardwerts vom Typ TObtain default value of type T
delegate {...} Anonyme Funktion (anonyme Methode)Anonymous function (anonymous method)
UnärUnary +x IdentitätIdentity
-x NegationNegation
!x Logische NegationLogical negation
~x Bitweise NegationBitwise negation
++x PräinkrementPre-increment
--x PrädekrementPre-decrement
(T)x Explizites Konvertieren von x in den Typ TExplicitly convert x to type T
await x Asynchrones Warten auf den Abschluss von xAsynchronously wait for x to complete
MultiplikativMultiplicative x * y MultiplikationMultiplication
x / y DivisionDivision
x % y RestRemainder
AdditivAdditive x + y Addition, Zeichenfolgenverkettung, DelegatkombinationAddition, string concatenation, delegate combination
x - y Subtraktion, DelegatentfernungSubtraction, delegate removal
ShiftShift x << y LinksverschiebungShift left
x >> y RechtsverschiebungShift right
Relational und TyptestRelational and type testing x < y Kleiner alsLess than
x > y Größer alsGreater than
x <= y Kleiner oder gleichLess than or equal
x >= y Größer oder gleichGreater than or equal
x is T true zurückgeben, wenn x ein T ist, andernfalls falseReturn true if x is a T, false otherwise
x as T x als T typisiert zurückgeben, oder null, wenn x kein T istReturn x typed as T, or null if x is not a T
GleichheitEquality x == y GleichEqual
x != y UngleichNot equal
Logisches ANDLogical AND x & y Ganzzahliges bitweises AND, boolesches logisches ANDInteger bitwise AND, boolean logical AND
Logisches XORLogical XOR x ^ y Ganzzahliges bitweises XOR, boolesches logisches XORInteger bitwise XOR, boolean logical XOR
Logisches ORLogical OR x | y Ganzzahliges bitweises OR, boolesches logisches ORInteger bitwise OR, boolean logical OR
Bedingtes ANDConditional AND x && y Wertet y nur aus x , wenntrueEvaluates y only if x is true
Bedingtes ORConditional OR x || y Wertet y nur aus x , wennfalseEvaluates y only if x is false
NULL-SammeloperatorNull coalescing x ?? y Ergibt, x Wennistnull ,x andernfalls. yEvaluates to y if x is null, to x otherwise
BedingtConditional x ? y : z Wertet y aus, wenn x true ist, z, wenn x false istEvaluates y if x is true, z if x is false
Zuweisung oder anonyme FunktionAssignment or anonymous function x = y ZuweisungAssignment
x op= y Verbund Zuweisung; Unterstützte Operatoren sind *= /= %= += -= <<= >>= &= ^=|=Compound assignment; supported operators are *= /= %= += -= <<= >>= &= ^= |=
(T x) => y Anonyme Funktion (Lambda-Ausdruck)Anonymous function (lambda expression)

AnweisungenStatements

Die Aktionen eines Programms werden mit Anweisungen ausgedrückt.The actions of a program are expressed using statements. C# unterstützt verschiedene Arten von Anweisungen, von denen ein Teil als eingebettete Anweisungen definiert ist.C# supports several different kinds of statements, a number of which are defined in terms of embedded statements.

Ein Block ermöglicht, mehrere Anweisungen in Kontexten zu schreiben, in denen eine einzelne Anweisung zulässig ist.A block permits multiple statements to be written in contexts where a single statement is allowed. Ein Block besteht aus einer Liste von Anweisungen, die zwischen den Trennzeichen { und } geschrieben sind.A block consists of a list of statements written between the delimiters { and }.

Deklarationsanweisungen werden verwendet, um lokale Variablen und Konstanten deklarieren.Declaration statements are used to declare local variables and constants.

Ausdrucksanweisungen werden zum Auswerten von Ausdrücken verwendet.Expression statements are used to evaluate expressions. Ausdrücke, die als Anweisungen verwendet werden können, umfassen Methodenaufrufe, Objekt Zuordnungen new mit dem-Operator = , Zuweisungen mit und die Verbund Zuweisungs Operatoren, Inkrement-und dekrementvorgänge mithilfe des ++and -- -Operatoren und-Ausdrücke warten.Expressions that can be used as statements include method invocations, object allocations using the new operator, assignments using = and the compound assignment operators, increment and decrement operations using the ++ and -- operators and await expressions.

Auswahlanweisungen werden verwendet, um eine Anzahl von möglichen Anweisungen für die Ausführung anhand des Werts eines Ausdrucks auszuwählen.Selection statements are used to select one of a number of possible statements for execution based on the value of some expression. Zu dieser Gruppe gehören die if- und switch-Anweisungen.In this group are the if and switch statements.

Iterations Anweisungen werden verwendet, um eine eingebettete Anweisung wiederholt auszuführen.Iteration statements are used to repeatedly execute an embedded statement. Zu dieser Gruppe gehören die while-, do-, for- und foreach-Anweisungen.In this group are the while, do, for, and foreach statements.

Sprunganweisungen werden verwendet, um die Steuerung zu übertragen.Jump statements are used to transfer control. Zu dieser Gruppe gehören die break-, continue-, goto-, throw-, return- und yield-Anweisungen.In this group are the break, continue, goto, throw, return, and yield statements.

Mit der try... catch-Anweisung werden Ausnahmen abgefangen, die während der Ausführung eines Blocks auftreten, und mit der try... finally-Anweisung wird Finalisierungscode angegeben, der immer ausgeführt wird, unabhängig davon, ob eine Ausnahme aufgetreten ist oder nicht.The try...catch statement is used to catch exceptions that occur during execution of a block, and the try...finally statement is used to specify finalization code that is always executed, whether an exception occurred or not.

Die checked - unchecked und-Anweisungen werden verwendet, um den Überlauf Überprüfungs Kontext für arithmetische Operationen im ganzzahligen Typ und Konvertierungen zu steuern.The checked and unchecked statements are used to control the overflow checking context for integral-type arithmetic operations and conversions.

Die lock-Anweisung wird verwendet, um die Sperre für gegenseitigen Ausschluss für ein bestimmtes Objekt abzurufen, eine Anweisung auszuführen und die Sperre aufzuheben.The lock statement is used to obtain the mutual-exclusion lock for a given object, execute a statement, and then release the lock.

Die using-Anweisung wird verwendet, um eine Ressource abzurufen, eine Anweisung auszuführen und dann diese Ressource zu verwerfen.The using statement is used to obtain a resource, execute a statement, and then dispose of that resource.

Im folgenden finden Sie Beispiele für jede Art von Anweisung.Below are examples of each kind of statement

Deklarationen von lokalen VariablenLocal variable declarations

static void Main() {
   int a;
   int b = 2, c = 3;
   a = 1;
   Console.WriteLine(a + b + c);
}

Deklaration der lokalen KonstanteLocal constant declaration

static void Main() {
    const float pi = 3.1415927f;
    const int r = 25;
    Console.WriteLine(pi * r * r);
}

Expression-AnweisungExpression statement

static void Main() {
    int i;
    i = 123;                // Expression statement
    Console.WriteLine(i);   // Expression statement
    i++;                    // Expression statement
    Console.WriteLine(i);   // Expression statement
}

if-Anweisungif statement

static void Main(string[] args) {
    if (args.Length == 0) {
        Console.WriteLine("No arguments");
    }
    else {
        Console.WriteLine("One or more arguments");
    }
}

switch-Anweisungswitch statement

static void Main(string[] args) {
    int n = args.Length;
    switch (n) {
        case 0:
            Console.WriteLine("No arguments");
            break;
        case 1:
            Console.WriteLine("One argument");
            break;
        default:
            Console.WriteLine("{0} arguments", n);
            break;
    }
}

while-Anweisungwhile statement

static void Main(string[] args) {
    int i = 0;
    while (i < args.Length) {
        Console.WriteLine(args[i]);
        i++;
    }
}

do-Anweisungdo statement

static void Main() {
    string s;
    do {
        s = Console.ReadLine();
        if (s != null) Console.WriteLine(s);
    } while (s != null);
}

for-Anweisungfor statement

static void Main(string[] args) {
    for (int i = 0; i < args.Length; i++) {
        Console.WriteLine(args[i]);
    }
}

foreach-Anweisungforeach statement

static void Main(string[] args) {
    foreach (string s in args) {
        Console.WriteLine(s);
    }
}

break-Anweisungbreak statement

static void Main() {
    while (true) {
        string s = Console.ReadLine();
        if (s == null) break;
        Console.WriteLine(s);
    }
}

continue-Anweisungcontinue statement

static void Main(string[] args) {
    for (int i = 0; i < args.Length; i++) {
        if (args[i].StartsWith("/")) continue;
        Console.WriteLine(args[i]);
    }
}

goto-Anweisunggoto statement

static void Main(string[] args) {
    int i = 0;
    goto check;
    loop:
    Console.WriteLine(args[i++]);
    check:
    if (i < args.Length) goto loop;
}

return-Anweisungreturn statement

static int Add(int a, int b) {
    return a + b;
}

static void Main() {
    Console.WriteLine(Add(1, 2));
    return;
}

yield-Anweisungyield statement

static IEnumerable<int> Range(int from, int to) {
    for (int i = from; i < to; i++) {
        yield return i;
    }
    yield break;
}

static void Main() {
    foreach (int x in Range(-10,10)) {
        Console.WriteLine(x);
    }
}

throwund try -Anweisungenthrow and try statements

static double Divide(double x, double y) {
    if (y == 0) throw new DivideByZeroException();
    return x / y;
}

static void Main(string[] args) {
    try {
        if (args.Length != 2) {
            throw new Exception("Two numbers required");
        }
        double x = double.Parse(args[0]);
        double y = double.Parse(args[1]);
        Console.WriteLine(Divide(x, y));
    }
    catch (Exception e) {
        Console.WriteLine(e.Message);
    }
    finally {
        Console.WriteLine("Good bye!");
    }
}

checkedund unchecked -Anweisungenchecked and unchecked statements

static void Main() {
    int i = int.MaxValue;
    checked {
        Console.WriteLine(i + 1);        // Exception
    }
    unchecked {
        Console.WriteLine(i + 1);        // Overflow
    }
}

lock-Anweisunglock statement

class Account
{
    decimal balance;
    public void Withdraw(decimal amount) {
        lock (this) {
            if (amount > balance) {
                throw new Exception("Insufficient funds");
            }
            balance -= amount;
        }
    }
}

using-Anweisungusing statement

static void Main() {
    using (TextWriter w = File.CreateText("test.txt")) {
        w.WriteLine("Line one");
        w.WriteLine("Line two");
        w.WriteLine("Line three");
    }
}

Klassen und ObjekteClasses and objects

Klassen sind die grundlegendsten der C#-Typen.Classes are the most fundamental of C#'s types. Eine Klasse ist eine Datenstruktur, die einen Zustand (Felder) und Aktionen (Methoden und andere Funktionsmember) in einer einzigen Einheit kombiniert.A class is a data structure that combines state (fields) and actions (methods and other function members) in a single unit. Eine Klasse stellt eine Definition für dynamisch erstellte Instanzen der Klasse, auch bekannt als Objekte bereit.A class provides a definition for dynamically created instances of the class, also known as objects. Klassen unterstützen Vererbung und Polymorphie. Dies sind Mechanismen, durch die abgeleitete Klassen erweitert und Basisklassen spezialisiert werden können.Classes support inheritance and polymorphism, mechanisms whereby derived classes can extend and specialize base classes.

Neue Klassen werden mithilfe von Klassendeklarationen erstellt.New classes are created using class declarations. Eine Klassendeklaration beginnt mit einem Header, der die Attribute und Modifizierer der Klasse, den Namen der Klasse, die Basisklasse (sofern vorhanden) und die von der Klasse implementierten Schnittstellen angibt.A class declaration starts with a header that specifies the attributes and modifiers of the class, the name of the class, the base class (if given), and the interfaces implemented by the class. Auf den Header folgt der Klassenkörper. Dieser besteht aus einer Liste der Memberdeklarationen, die zwischen den Trennzeichen { und } eingefügt werden.The header is followed by the class body, which consists of a list of member declarations written between the delimiters { and }.

Nachfolgend sehen Sie eine Deklaration einer einfachen Klasse namens Point:The following is a declaration of a simple class named Point:

public class Point
{
    public int x, y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

Instanzen von Klassen werden mit dem new-Operator erstellt. Dieser reserviert Speicher für eine neue Instanz, ruft einen Konstruktor zum Initialisieren der Instanz auf und gibt einen Verweis auf die Instanz zurück.Instances of classes are created using the new operator, which allocates memory for a new instance, invokes a constructor to initialize the instance, and returns a reference to the instance. Mit den folgenden-Anweisungen Point werden zwei-Objekte erstellt und Verweise auf diese Objekte in zwei Variablen gespeichert:The following statements create two Point objects and store references to those objects in two variables:

Point p1 = new Point(0, 0);
Point p2 = new Point(10, 20);

Der von einem Objekt belegte Arbeitsspeicher wird automatisch freigegeben, wenn das Objekt nicht mehr verwendet wird.The memory occupied by an object is automatically reclaimed when the object is no longer in use. Es ist weder erforderlich noch möglich, die Zuweisung von Objekten in C# explizit aufzuheben.It is neither necessary nor possible to explicitly deallocate objects in C#.

MemberMembers

Die Member einer Klasse sind entweder statische Member oder Instanzmember.The members of a class are either static members or instance members. Statische Member gehören zu Klassen, Instanzmember gehören zu Objekten (Instanzen von Klassen).Static members belong to classes, and instance members belong to objects (instances of classes).

Die folgende Tabelle enthält eine Übersicht über die Arten von Membern, die eine Klasse enthalten kann.The following table provides an overview of the kinds of members a class can contain.

KollegeMember BeschreibungDescription
KonstantenConstants Konstante Werte, die der Klasse zugeordnet sindConstant values associated with the class
FelderFields Variablen der KlasseVariables of the class
MethodenMethods Berechnungen und Aktionen, die von der Klasse ausgeführt werdenComputations and actions that can be performed by the class
EigenschaftenProperties Aktionen im Zusammenhang mit dem Lesen und Schreiben von benannten Eigenschaften der KlasseActions associated with reading and writing named properties of the class
IndexerIndexers Aktionen im Zusammenhang mit dem Indizieren von Instanzen der Klasse, z.B. einem ArrayActions associated with indexing instances of the class like an array
EreignisseEvents Benachrichtigungen, die von der Klasse generiert werden könnenNotifications that can be generated by the class
OperatorenOperators Operatoren für Konvertierungen und Ausdrücke, die von der Klasse unterstützt werdenConversions and expression operators supported by the class
KonstruktorenConstructors Aktionen, die zum Initialisieren von Instanzen der Klasse oder der Klasse selbst benötigt werdenActions required to initialize instances of the class or the class itself
DestruktorenDestructors Aktionen, die ausgeführt werden, bevor Instanzen der Klasse dauerhaft verworfen werdenActions to perform before instances of the class are permanently discarded
TypenTypes Geschachtelte Typen, die von der Klasse deklariert werdenNested types declared by the class

ZugriffAccessibility

Jeder Member einer Klasse ist mit einem Zugriff verknüpft, der die Regionen des Programmtexts steuert, die auf den Member zugreifen können.Each member of a class has an associated accessibility, which controls the regions of program text that are able to access the member. Es gibt fünf mögliche Formen des Zugriffs.There are five possible forms of accessibility. Diese werden in der folgenden Tabelle zusammengefasst.These are summarized in the following table.

BarrierefreiheitAccessibility D.h.Meaning
public Der Zugriff ist nicht eingeschränkt.Access not limited
protected Der Zugriff ist auf diese Klasse oder auf von dieser Klasse abgeleitete Klassen beschränkt.Access limited to this class or classes derived from this class
internal Der Zugriff ist auf dieses Programm beschränkt.Access limited to this program
protected internal Der Zugriff ist auf dieses Programm oder auf von dieser Klasse abgeleitete Klassen beschränkt.Access limited to this program or classes derived from this class
private Der Zugriff ist auf diese Klasse beschränkt.Access limited to this class

TypparameterType parameters

Eine Klassendefinition kann einen Satz an Typparametern angeben, indem eine Liste der Typparameternamen in spitzen Klammern an den Klassennamen angehängt wird.A class definition may specify a set of type parameters by following the class name with angle brackets enclosing a list of type parameter names. Die Typparameter können im Text der Klassen Deklarationen verwendet werden, um die Member der Klasse zu definieren.The type parameters can the be used in the body of the class declarations to define the members of the class. Im folgenden Beispiel lauten die Typparameter von Pair TFirst und TSecond:In the following example, the type parameters of Pair are TFirst and TSecond:

public class Pair<TFirst,TSecond>
{
    public TFirst First;
    public TSecond Second;
}

Ein Klassentyp, der als Typparameter deklariert wird, wird als generischer Klassentyp bezeichnet.A class type that is declared to take type parameters is called a generic class type. Struktur-, Schnittstellen- und Delegattypen können auch generisch sein.Struct, interface and delegate types can also be generic.

Wenn die generische Klasse verwendet wird, müssen für jeden der Typparameter Typargumente angegeben werden:When the generic class is used, type arguments must be provided for each of the type parameters:

Pair<int,string> pair = new Pair<int,string> { First = 1, Second = "two" };
int i = pair.First;     // TFirst is int
string s = pair.Second; // TSecond is string

Ein generischer Typ mit Typargumenten Pair<int,string> , wie oben angegeben, wird als konstruierter Typ bezeichnet.A generic type with type arguments provided, like Pair<int,string> above, is called a constructed type.

BasisklassenBase classes

Eine Klassendeklaration kann eine Basisklasse angeben, indem ein Doppelpunkt und der Name der Basisklasse an den Klassennamen und die Typparameter angehängt wird.A class declaration may specify a base class by following the class name and type parameters with a colon and the name of the base class. Das Auslassen einer Basisklassenspezifikation ist dasselbe wie eine Ableitung vom Typ object.Omitting a base class specification is the same as deriving from type object. Im folgenden Beispiel ist Point die Basisklasse von Point3D, und die Basisklasse von Point ist object:In the following example, the base class of Point3D is Point, and the base class of Point is object:

public class Point
{
    public int x, y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

public class Point3D: Point
{
    public int z;

    public Point3D(int x, int y, int z): base(x, y) {
        this.z = z;
    }
}

Eine Klasse erbt die Member der zugehörigen Basisklasse.A class inherits the members of its base class. Vererbung bedeutet, dass eine Klasse implizit alle Member der Basisklasse enthält, mit Ausnahme der Instanzkonstruktoren und statischen Konstruktoren sowie der Dekonstruktoren der Basisklasse.Inheritance means that a class implicitly contains all members of its base class, except for the instance and static constructors, and the destructors of the base class. Eine abgeleitete Klasse kann den geerbten Membern neue Member hinzufügen, aber die Definition eines geerbten Members kann nicht entfernt werden.A derived class can add new members to those it inherits, but it cannot remove the definition of an inherited member. Im vorherigen Beispiel erbt Point3D die Felder x und y von Point, und jede Point3D-Instanz enthält drei Felder: x, y und z.In the previous example, Point3D inherits the x and y fields from Point, and every Point3D instance contains three fields, x, y, and z.

Ein Klassentyp kann implizit in einen beliebigen zugehörigen Basisklassentyp konvertiert werden.An implicit conversion exists from a class type to any of its base class types. Deshalb kann eine Variable eines Klassentyps auf eine Instanz dieser Klasse oder auf eine Instanz einer beliebigen abgeleiteten Klasse verweisen.Therefore, a variable of a class type can reference an instance of that class or an instance of any derived class. Beispielsweise kann in den vorherigen Klassendeklarationen eine Variable vom Typ Point entweder auf Point oder auf Point3D verweisen:For example, given the previous class declarations, a variable of type Point can reference either a Point or a Point3D:

Point a = new Point(10, 20);
Point b = new Point3D(10, 20, 30);

FelderFields

Ein Feld ist eine Variable, die einer Klasse oder einer Instanz einer Klasse zugeordnet ist.A field is a variable that is associated with a class or with an instance of a class.

Ein mit dem static -Modifizierer deklarierter Feld definiert ein statisches Feld.A field declared with the static modifier defines a static field. Ein statisches Feld identifiziert genau einen Speicherort.A static field identifies exactly one storage location. Unabhängig davon, wie viele Instanzen einer Klasse erstellt werden, gibt es nur eine Kopie eines statischen Felds.No matter how many instances of a class are created, there is only ever one copy of a static field.

Ein Feld, das ohne static den Modifizierer deklariert wurde, definiert ein Instanzfeld.A field declared without the static modifier defines an instance field. Jede Instanz einer Klasse enthält eine separate Kopie aller Instanzfelder dieser Klasse.Every instance of a class contains a separate copy of all the instance fields of that class.

Im folgenden Beispiel weist jede Instanz der Color-Klasse eine separate Kopie der Instanzfelder r, g und b auf, aber es gibt nur eine Kopie der statischen Felder Black, White, Red, Green und Blue:In the following example, each instance of the Color class has a separate copy of the r, g, and b instance fields, but there is only one copy of the Black, White, Red, Green, and Blue static fields:

public class Color
{
    public static readonly Color Black = new Color(0, 0, 0);
    public static readonly Color White = new Color(255, 255, 255);
    public static readonly Color Red = new Color(255, 0, 0);
    public static readonly Color Green = new Color(0, 255, 0);
    public static readonly Color Blue = new Color(0, 0, 255);
    private byte r, g, b;

    public Color(byte r, byte g, byte b) {
        this.r = r;
        this.g = g;
        this.b = b;
    }
}

Wie im vorherigen Beispiel gezeigt, können schreibgeschützte Felder mit einem readonly-Modifizierer deklariert werden.As shown in the previous example, read-only fields may be declared with a readonly modifier. Die Zuweisung zu readonly einem Feld kann nur als Teil der Deklaration des Felds oder in einem Konstruktor in derselben Klasse erfolgen.Assignment to a readonly field can only occur as part of the field's declaration or in a constructor in the same class.

MethodenMethods

Eine Methode ist ein Member, das eine Berechnung oder eine Aktion implementiert, die durch ein Objekt oder eine Klasse durchgeführt werden kann.A method is a member that implements a computation or action that can be performed by an object or class. Auf statische Methoden wird über die Klasse zugegriffen.Static methods are accessed through the class. Auf Instanzmethoden wird über Instanzen der Klasse zugegriffen.Instance methods are accessed through instances of the class.

Methoden verfügen über eine (möglicherweise leere) Liste von Parametern, die Werte oder Variablen Verweise darstellen, die an die Methode übermittelt werden, und einen Rückgabetyp, der den Typ des Werts angibt, der von der Methode berechnet und zurückgegeben wird.Methods have a (possibly empty) list of parameters, which represent values or variable references passed to the method, and a return type, which specifies the type of the value computed and returned by the method. Der Rückgabetyp einer void Methode ist, wenn Sie keinen Wert zurückgibt.A method's return type is void if it does not return a value.

Ebenso wie Typen können Methoden einen Satz an Typparametern aufweisen, für den beim Aufruf der Methode Typargumente angegeben werden müssen.Like types, methods may also have a set of type parameters, for which type arguments must be specified when the method is called. Im Gegensatz zu Typen können die Typargumente häufig aus den Argumenten eines Methodenaufrufs abgeleitet werden und müssen nicht explizit angegeben werden.Unlike types, the type arguments can often be inferred from the arguments of a method call and need not be explicitly given.

Die Signatur einer Methode muss innerhalb der Klasse eindeutig sein, in der die Methode deklariert ist.The signature of a method must be unique in the class in which the method is declared. Die Signatur einer Methode besteht aus dem Namen der Methode, der Anzahl von Typparametern und der Anzahl, den Modifizierern und den Typen der zugehörigen Parameter.The signature of a method consists of the name of the method, the number of type parameters and the number, modifiers, and types of its parameters. Die Signatur einer Methode umfasst nicht den Rückgabetyp.The signature of a method does not include the return type.

ParameterParameters

Parameter werden dazu verwendet, Werte oder Variablenverweise an Methoden zu übergeben.Parameters are used to pass values or variable references to methods. Die Parameter einer Methode erhalten ihre tatsächlichen Werte über Argumente, die angegeben werden, wenn die Methode aufgerufen wird.The parameters of a method get their actual values from the arguments that are specified when the method is invoked. Es gibt vier Arten von Parametern: Wertparameter, Verweisparameter, Ausgabeparameter und Parameterarrays.There are four kinds of parameters: value parameters, reference parameters, output parameters, and parameter arrays.

Ein Wertparameter wird zum Übergeben von Eingabeparametern verwendet.A value parameter is used for input parameter passing. Ein Wertparameter entspricht einer lokalen Variablen, die ihren Anfangswert von dem Argument erhält, das für den Parameter übergeben wurde.A value parameter corresponds to a local variable that gets its initial value from the argument that was passed for the parameter. Änderungen an einem Wertparameter wirken sich nicht auf das Argument aus, das für den Parameter übergeben wurde.Modifications to a value parameter do not affect the argument that was passed for the parameter.

Wertparameter können optional sein, indem ein Standardwert festgelegt wird, damit die zugehörigen Argumente weggelassen werden können.Value parameters can be optional, by specifying a default value so that corresponding arguments can be omitted.

Ein Verweisparameter wird sowohl für die Übergabe von Eingabe- als auch Ausgabeparametern verwendet.A reference parameter is used for both input and output parameter passing. Das für einen Verweisparameter übergebene Argument muss eine Variable sein, und während der Ausführung der Methode repräsentiert der Verweisparameter denselben Speicherort wie die Argumentvariable.The argument passed for a reference parameter must be a variable, and during execution of the method, the reference parameter represents the same storage location as the argument variable. Ein Verweisparameter wird mit dem ref-Modifizierer deklariert.A reference parameter is declared with the ref modifier. Das folgende Beispiel veranschaulicht die Verwendung des ref-Parameters.The following example shows the use of ref parameters.

using System;

class Test
{
    static void Swap(ref int x, ref int y) {
        int temp = x;
        x = y;
        y = temp;
    }

    static void Main() {
        int i = 1, j = 2;
        Swap(ref i, ref j);
        Console.WriteLine("{0} {1}", i, j);            // Outputs "2 1"
    }
}

Ein Ausgabeparameter wird zum Übergeben von Ausgabeparametern verwendet.An output parameter is used for output parameter passing. Ein Ausgabeparameter ähnelt einem Verweisparameter, mit dem Unterschied, dass der Anfangswert des vom Aufrufer bereitgestellten Arguments nicht von Bedeutung ist.An output parameter is similar to a reference parameter except that the initial value of the caller-provided argument is unimportant. Ein Ausgabeparameter wird mit dem out-Modifizierer deklariert.An output parameter is declared with the out modifier. Das folgende Beispiel veranschaulicht die Verwendung des out-Parameters.The following example shows the use of out parameters.

using System;

class Test
{
    static void Divide(int x, int y, out int result, out int remainder) {
        result = x / y;
        remainder = x % y;
    }

    static void Main() {
        int res, rem;
        Divide(10, 3, out res, out rem);
        Console.WriteLine("{0} {1}", res, rem);    // Outputs "3 1"
    }
}

Ein Parameterarray ermöglicht es, eine variable Anzahl von Argumenten an eine Methode zu übergeben.A parameter array permits a variable number of arguments to be passed to a method. Ein Parameterarray wird mit dem params-Modifizierer deklariert.A parameter array is declared with the params modifier. Nur der letzte Parameter einer Methode kann ein Parameterarray sein, und es muss sich um ein eindimensionales Parameterarray handeln.Only the last parameter of a method can be a parameter array, and the type of a parameter array must be a single-dimensional array type. Die Write - WriteLine Methode und die System.Console -Methode der-Klasse sind gute Beispiele für die Verwendung von Parameter Arrays.The Write and WriteLine methods of the System.Console class are good examples of parameter array usage. Sie werden folgendermaßen deklariert.They are declared as follows.

public class Console
{
    public static void Write(string fmt, params object[] args) {...}
    public static void WriteLine(string fmt, params object[] args) {...}
    ...
}

Innerhalb einer Methode mit einem Parameterarray verhält sich das Parameterarray wie ein regulärer Parameter des Arraytyps.Within a method that uses a parameter array, the parameter array behaves exactly like a regular parameter of an array type. Beim Aufruf einer Methode mit einem Parameterarray ist es jedoch möglich, entweder ein einzelnes Argument des Parameterarraytyps oder eine beliebige Anzahl von Argumenten des Elementtyps des Parameterarrays zu übergeben.However, in an invocation of a method with a parameter array, it is possible to pass either a single argument of the parameter array type or any number of arguments of the element type of the parameter array. Im letzteren Fall wird automatisch eine Arrayinstanz erstellt und mit den vorgegebenen Argumenten initialisiert.In the latter case, an array instance is automatically created and initialized with the given arguments. Dieses Beispiel:This example

Console.WriteLine("x={0} y={1} z={2}", x, y, z);

...entspricht dem folgenden Code:is equivalent to writing the following.

string s = "x={0} y={1} z={2}";
object[] args = new object[3];
args[0] = x;
args[1] = y;
args[2] = z;
Console.WriteLine(s, args);

Methodenkörper und lokale VariablenMethod body and local variables

Der Text einer Methode gibt die-Anweisungen an, die beim Aufrufen der-Methode ausgeführt werden sollen.A method's body specifies the statements to execute when the method is invoked.

Ein Methodenkörper kann Variablen deklarieren, die für den Aufruf der Methode spezifisch sind.A method body can declare variables that are specific to the invocation of the method. Diese Variable werden lokale Variablen genannt.Such variables are called local variables. Die Deklaration einer lokalen Variable gibt einen Typnamen, einen Variablennamen und eventuell einen Anfangswert an.A local variable declaration specifies a type name, a variable name, and possibly an initial value. Im folgenden Beispiel wird eine lokale Variable i mit einem Anfangswert von 0 und einer lokalen Variablen j ohne Anfangswert deklariert.The following example declares a local variable i with an initial value of zero and a local variable j with no initial value.

using System;

class Squares
{
    static void Main() {
        int i = 0;
        int j;
        while (i < 10) {
            j = i * i;
            Console.WriteLine("{0} x {0} = {1}", i, j);
            i = i + 1;
        }
    }
}

In C# muss eine lokale Variable definitiv zugewiesen sein, bevor ihr Wert abgerufen werden kann.C# requires a local variable to be definitely assigned before its value can be obtained. Wenn beispielsweise die vorherige Deklaration von i keinen Anfangswert enthielte, würde der Compiler bei der nachfolgenden Verwendung von i einen Fehler melden, weil i zu diesen Zeitpunkten im Programm nicht definitiv zugewiesen wäre.For example, if the declaration of the previous i did not include an initial value, the compiler would report an error for the subsequent usages of i because i would not be definitely assigned at those points in the program.

Eine Methode kann return-Anweisungen verwenden, um die Steuerung an den zugehörigen Aufrufer zurückzugeben.A method can use return statements to return control to its caller. In einer Methode, die void zurückgibt, können return-Anweisungen keinen Ausdruck angeben.In a method returning void, return statements cannot specify an expression. In einer Methode, die nichtvoid- return -Anweisungen zurückgibt, müssen-Anweisungen einen Ausdruck enthalten, der den Rückgabewert berechnet.In a method returning non-void, return statements must include an expression that computes the return value.

Statische Methoden und InstanzmethodenStatic and instance methods

Eine Methode, die mit static einem-Modifizierer deklariert wird, ist eine statische Methode.A method declared with a static modifier is a static method. Eine statische Methode führt keine Vorgänge für eine spezifische Instanz aus und kann nur direkt auf statische Member zugreifen.A static method does not operate on a specific instance and can only directly access static members.

Eine Methode, die ohne static Modifizierer deklariert wird, ist eine Instanzmethode.A method declared without a static modifier is an instance method. Eine Instanzmethode führt Vorgänge für eine spezifische Instanz aus und kann sowohl auf statische Member als auch auf Instanzmember zugreifen.An instance method operates on a specific instance and can access both static and instance members. Auf die Instanz, für die eine Instanzmethode aufgerufen wurde, kann explizit als this zugegriffen werden.The instance on which an instance method was invoked can be explicitly accessed as this. Es ist ein Fehler, in einer statischen Methode auf this zu verweisen.It is an error to refer to this in a static method.

Die folgende Entity-Klasse umfasst sowohl statische Member als auch Instanzmember.The following Entity class has both static and instance members.

class Entity
{
    static int nextSerialNo;
    int serialNo;

    public Entity() {
        serialNo = nextSerialNo++;
    }

    public int GetSerialNo() {
        return serialNo;
    }

    public static int GetNextSerialNo() {
        return nextSerialNo;
    }

    public static void SetNextSerialNo(int value) {
        nextSerialNo = value;
    }
}

Jede Entity-Instanz enthält eine Seriennummer (und vermutlich weitere Informationen, die hier nicht angezeigt werden).Each Entity instance contains a serial number (and presumably some other information that is not shown here). Der Entity-Konstruktor (der einer Instanzmethode ähnelt) initialisiert die neue Instanz mit der nächsten verfügbaren Seriennummer.The Entity constructor (which is like an instance method) initializes the new instance with the next available serial number. Da der Konstruktor ein Instanzmember ist, kann er sowohl auf das serialNo-Instanzfeld als auch auf das statische nextSerialNo-Feld zugreifen.Because the constructor is an instance member, it is permitted to access both the serialNo instance field and the nextSerialNo static field.

Die statischen Methoden GetNextSerialNo und SetNextSerialNo können auf das statische Feld nextSerialNo zugreifen, aber es wäre ein Fehler, über diese Methoden direkt auf das Instanzfeld serialNo zuzugreifen.The GetNextSerialNo and SetNextSerialNo static methods can access the nextSerialNo static field, but it would be an error for them to directly access the serialNo instance field.

Im folgenden Beispiel wird die Verwendung Entity der-Klasse veranschaulicht.The following example shows the use of the Entity class.

using System;

class Test
{
    static void Main() {
        Entity.SetNextSerialNo(1000);
        Entity e1 = new Entity();
        Entity e2 = new Entity();
        Console.WriteLine(e1.GetSerialNo());           // Outputs "1000"
        Console.WriteLine(e2.GetSerialNo());           // Outputs "1001"
        Console.WriteLine(Entity.GetNextSerialNo());   // Outputs "1002"
    }
}

Beachten Sie, dass die statischen Methoden SetNextSerialNo und GetNextSerialNo für die Klasse aufgerufen werden, während die GetSerialNo-Instanzmethode für Instanzen der Klasse aufgerufen wird.Note that the SetNextSerialNo and GetNextSerialNo static methods are invoked on the class whereas the GetSerialNo instance method is invoked on instances of the class.

Virtuelle, überschriebene und abstrakte MethodenVirtual, override, and abstract methods

Wenn die Deklaration einer Instanzmethode einen virtual-Modifizierer enthält, wird die Methode als virtuelle Methode bezeichnet.When an instance method declaration includes a virtual modifier, the method is said to be a virtual method. Wenn kein virtual Modifizierer vorhanden ist, wird die Methode als nicht virtuelle Methodebezeichnet.When no virtual modifier is present, the method is said to be a non-virtual method.

Beim Aufruf einer virtuellen Methode bestimmt der Laufzeittyp der Instanz, für die der Aufruf erfolgt, die tatsächlich aufzurufende Methodenimplementierung.When a virtual method is invoked, the run-time type of the instance for which that invocation takes place determines the actual method implementation to invoke. Beim Aufruf einer nicht virtuellen Methode ist der Kompilierzeittyp der bestimmende Faktor.In a nonvirtual method invocation, the compile-time type of the instance is the determining factor.

Eine virtuelle Methode kann in einer abgeleiteten Klasse überschrieben werden.A virtual method can be overridden in a derived class. Wenn eine Instanzmethodendeklaration einen override Modifizierer enthält, überschreibt die Methode eine geerbte virtuelle Methode mit derselben Signatur.When an instance method declaration includes an override modifier, the method overrides an inherited virtual method with the same signature. Während eine Deklaration einer virtuellen Methode eine neue Methode einführt, spezialisiert eine Deklaration einer überschriebenen Methode eine vorhandene geerbte virtuelle Methode, indem eine neue Implementierung dieser Methode bereitgestellt wird.Whereas a virtual method declaration introduces a new method, an override method declaration specializes an existing inherited virtual method by providing a new implementation of that method.

Eine abstrakte Methode ist eine virtuelle Methode ohne Implementierung.An abstract method is a virtual method with no implementation. Eine abstrakte Methode wird mit dem abstract -Modifizierer deklariert und ist nur in einer Klasse zulässig, die ebenfalls deklariert abstractwird.An abstract method is declared with the abstract modifier and is permitted only in a class that is also declared abstract. Eine abstrakte Methode muss in jeder nicht abstrakten abgeleiteten Klasse überschrieben werden.An abstract method must be overridden in every non-abstract derived class.

Im folgenden Beispiel wird die abstrakte Klasse Expression deklariert, die einen Ausdrucksbaumstrukturknoten sowie drei abgeleitete Klassen repräsentiert: Constant, VariableReference und Operation. Diese implementieren Ausdrucksbaumstrukturknoten für Konstanten, variable Verweise und arithmetische Operationen.The following example declares an abstract class, Expression, which represents an expression tree node, and three derived classes, Constant, VariableReference, and Operation, which implement expression tree nodes for constants, variable references, and arithmetic operations. (Dies ist vergleichbar mit, sollte jedoch nicht mit den Ausdrucks Baum Typen verwechselt werden, die in Ausdrucks Baumstruktur Typeneingeführt wurden).(This is similar to, but not to be confused with the expression tree types introduced in Expression tree types).

using System;
using System.Collections;

public abstract class Expression
{
    public abstract double Evaluate(Hashtable vars);
}

public class Constant: Expression
{
    double value;

    public Constant(double value) {
        this.value = value;
    }

    public override double Evaluate(Hashtable vars) {
        return value;
    }
}

public class VariableReference: Expression
{
    string name;

    public VariableReference(string name) {
        this.name = name;
    }

    public override double Evaluate(Hashtable vars) {
        object value = vars[name];
        if (value == null) {
            throw new Exception("Unknown variable: " + name);
        }
        return Convert.ToDouble(value);
    }
}

public class Operation: Expression
{
    Expression left;
    char op;
    Expression right;

    public Operation(Expression left, char op, Expression right) {
        this.left = left;
        this.op = op;
        this.right = right;
    }

    public override double Evaluate(Hashtable vars) {
        double x = left.Evaluate(vars);
        double y = right.Evaluate(vars);
        switch (op) {
            case '+': return x + y;
            case '-': return x - y;
            case '*': return x * y;
            case '/': return x / y;
        }
        throw new Exception("Unknown operator");
    }
}

Die vorherigen vier Klassen können zum Modellieren arithmetischer Ausdrücke verwendet werden.The previous four classes can be used to model arithmetic expressions. Beispielsweise kann mithilfe von Instanzen dieser Klassen der Ausdruck x + 3 folgendermaßen dargestellt werden.For example, using instances of these classes, the expression x + 3 can be represented as follows.

Expression e = new Operation(
    new VariableReference("x"),
    '+',
    new Constant(3));

Die Evaluate-Methode einer Expression-Instanz wird aufgerufen, um den vorgegebenen Ausdruck auszuwerten und einen double-Wert zu generieren.The Evaluate method of an Expression instance is invoked to evaluate the given expression and produce a double value. Die-Methode übernimmt als Argument Hashtable , das Variablennamen (als Schlüssel der Einträge) und Werte (als Werte der Einträge) enthält.The method takes as an argument a Hashtable that contains variable names (as keys of the entries) and values (as values of the entries). Die Evaluate -Methode ist eine virtuelle abstrakte Methode. Dies bedeutet, dass nicht abstrakte abgeleitete Klassen Sie überschreiben müssen, um eine tatsächliche Implementierung bereitzustellen.The Evaluate method is a virtual abstract method, meaning that non-abstract derived classes must override it to provide an actual implementation.

Eine Implementierung von Constant für Evaluate gibt lediglich die gespeicherte Konstante zurück.A Constant's implementation of Evaluate simply returns the stored constant. Die VariableReference-Implementierung von A sucht den Variablennamen in der Hash Tabelle und gibt den resultierenden Wert zurück.A VariableReference's implementation looks up the variable name in the hashtable and returns the resulting value. Eine Implementierung von Operation wertet zunächst (durch einen rekursiven Aufruf der zugehörigen Evaluate-Methoden) den linken und rechten Operanden aus und führt dann die vorgegebene arithmetische Operation aus.An Operation's implementation first evaluates the left and right operands (by recursively invoking their Evaluate methods) and then performs the given arithmetic operation.

Das folgende Programm verwendet die Expression-Klassen zum Auswerten des Ausdrucks x * (y + 2) für verschiedene Werte von x und y.The following program uses the Expression classes to evaluate the expression x * (y + 2) for different values of x and y.

using System;
using System.Collections;

class Test
{
    static void Main() {
        Expression e = new Operation(
            new VariableReference("x"),
            '*',
            new Operation(
                new VariableReference("y"),
                '+',
                new Constant(2)
            )
        );
        Hashtable vars = new Hashtable();
        vars["x"] = 3;
        vars["y"] = 5;
        Console.WriteLine(e.Evaluate(vars));        // Outputs "21"
        vars["x"] = 1.5;
        vars["y"] = 9;
        Console.WriteLine(e.Evaluate(vars));        // Outputs "16.5"
    }
}

MethodenüberladungMethod overloading

Das Überladen von Methoden macht es möglich, dass mehrere Methoden in derselben Klasse denselben Namen verwenden, solange sie eindeutige Signaturen aufweisen.Method overloading permits multiple methods in the same class to have the same name as long as they have unique signatures. Beim Kompilieren des Aufrufs einer überladenen Methode verwendet der Compiler die Überladungsauflösung, um die spezifische Methode zu ermitteln, die aufgerufen werden soll.When compiling an invocation of an overloaded method, the compiler uses overload resolution to determine the specific method to invoke. Mithilfe der Überladungsauflösung wird die Methode ermittelt, die den Argumenten am besten entspricht, bzw. es wird ein Fehler ausgegeben, wenn keine passende Methode gefunden wird.Overload resolution finds the one method that best matches the arguments or reports an error if no single best match can be found. Das folgende Beispiel zeigt die Verwendung der Überladungsauflösung.The following example shows overload resolution in effect. Der Kommentar für jeden Aufruf in der Main-Methode zeigt, welche Methode tatsächlich aufgerufen wird.The comment for each invocation in the Main method shows which method is actually invoked.

class Test
{
    static void F() {
        Console.WriteLine("F()");
    }

    static void F(object x) {
        Console.WriteLine("F(object)");
    }

    static void F(int x) {
        Console.WriteLine("F(int)");
    }

    static void F(double x) {
        Console.WriteLine("F(double)");
    }

    static void F<T>(T x) {
        Console.WriteLine("F<T>(T)");
    }

    static void F(double x, double y) {
        Console.WriteLine("F(double, double)");
    }

    static void Main() {
        F();                 // Invokes F()
        F(1);                // Invokes F(int)
        F(1.0);              // Invokes F(double)
        F("abc");            // Invokes F(object)
        F((double)1);        // Invokes F(double)
        F((object)1);        // Invokes F(object)
        F<int>(1);           // Invokes F<T>(T)
        F(1, 1);             // Invokes F(double, double)
    }
}

Wie im Beispiel gezeigt, kann eine bestimmte Methode immer ausgewählt werden, indem die Argumente explizit in die passenden Parametertypen konvertiert und/oder explizit Typargumente angegeben werden.As shown by the example, a particular method can always be selected by explicitly casting the arguments to the exact parameter types and/or explicitly supplying type arguments.

Andere FunktionsmemberOther function members

Member, die ausführbaren Code enthalten, werden als Funktionsmember einer Klasse bezeichnet.Members that contain executable code are collectively known as the function members of a class. In den vorangegangenen Abschnitten wurden die Methoden beschrieben, die wichtigste Form der Funktionsmember.The preceding section describes methods, which are the primary kind of function members. In diesem Abschnitt werden die anderen Arten von Funktionsmembern beschrieben, die von C#unterstützt werden: Konstruktoren, Eigenschaften, Indexer, Ereignisse, Operatoren und Dekonstruktoren.This section describes the other kinds of function members supported by C#: constructors, properties, indexers, events, operators, and destructors.

Der folgende Code zeigt eine generische Klasse mit List<T>dem Namen, die eine wachsende-Objektliste implementiert.The following code shows a generic class called List<T>, which implements a growable list of objects. Die Klasse enthält verschiedene Beispiele der gängigsten Arten von Funktionsmembern.The class contains several examples of the most common kinds of function members.

public class List<T> {
    // Constant...
    const int defaultCapacity = 4;

    // Fields...
    T[] items;
    int count;

    // Constructors...
    public List(int capacity = defaultCapacity) {
        items = new T[capacity];
    }

    // Properties...
    public int Count {
        get { return count; }
    }
    public int Capacity {
        get {
            return items.Length;
        }
        set {
            if (value < count) value = count;
            if (value != items.Length) {
                T[] newItems = new T[value];
                Array.Copy(items, 0, newItems, 0, count);
                items = newItems;
            }
        }
    }

    // Indexer...
    public T this[int index] {
        get {
            return items[index];
        }
        set {
            items[index] = value;
            OnChanged();
        }
    }

    // Methods...
    public void Add(T item) {
        if (count == Capacity) Capacity = count * 2;
        items[count] = item;
        count++;
        OnChanged();
    }
    protected virtual void OnChanged() {
        if (Changed != null) Changed(this, EventArgs.Empty);
    }
    public override bool Equals(object other) {
        return Equals(this, other as List<T>);
    }
    static bool Equals(List<T> a, List<T> b) {
        if (a == null) return b == null;
        if (b == null || a.count != b.count) return false;
        for (int i = 0; i < a.count; i++) {
            if (!object.Equals(a.items[i], b.items[i])) {
                return false;
            }
        }
        return true;
    }

    // Event...
    public event EventHandler Changed;

    // Operators...
    public static bool operator ==(List<T> a, List<T> b) {
        return Equals(a, b);
    }
    public static bool operator !=(List<T> a, List<T> b) {
        return !Equals(a, b);
    }
}

KonstruktorenConstructors

C# unterstützt sowohl Instanzkonstruktoren als auch statische Konstruktoren.C# supports both instance and static constructors. Ein Instanzkonstruktor ist ein Member, der die erforderlichen Aktionen zum Initialisieren einer Instanz einer Klasse implementiert.An instance constructor is a member that implements the actions required to initialize an instance of a class. Ein statischer Konstruktor ist ein Member, der die zum Initialisieren einer Klasse erforderlichen Aktionen implementiert, um die Klasse beim ersten Laden selbst zu initialisieren.A static constructor is a member that implements the actions required to initialize a class itself when it is first loaded.

Ein Konstruktor wird wie eine Methode ohne Rückgabetyp und mit demselben Namen wie die enthaltende Klasse deklariert.A constructor is declared like a method with no return type and the same name as the containing class. Wenn eine Konstruktordeklaration einen static Modifizierer enthält, wird ein statischer Konstruktor deklariert.If a constructor declaration includes a static modifier, it declares a static constructor. Andernfalls wird ein Instanzkonstruktor deklariert.Otherwise, it declares an instance constructor.

Instanzkonstruktoren können überladen werden.Instance constructors can be overloaded. Beispielsweise deklariert die List<T>-Klasse zwei Instanzkonstruktoren, einen ohne Parameter und einen weiteren mit einem int-Parameter.For example, the List<T> class declares two instance constructors, one with no parameters and one that takes an int parameter. Instanzkonstruktoren werden über den new-Operator aufgerufen.Instance constructors are invoked using the new operator. Die folgenden-Anweisungen weisen List<string> zwei-Instanzen zu, die jeden der Konstruktoren List der-Klasse verwenden.The following statements allocate two List<string> instances using each of the constructors of the List class.

List<string> list1 = new List<string>();
List<string> list2 = new List<string>(10);

Im Gegensatz zu anderen Members werden Instanzkonstruktoren nicht geerbt, und eine Klasse weist keine anderen Instanzkonstruktoren auf als diejenigen, die tatsächlich in der Klasse deklariert wurden.Unlike other members, instance constructors are not inherited, and a class has no instance constructors other than those actually declared in the class. Wenn kein Instanzkonstruktor für eine Klasse angegeben ist, wird automatisch ein leerer Instanzkonstruktor ohne Parameter bereitgestellt.If no instance constructor is supplied for a class, then an empty one with no parameters is automatically provided.

EigenschaftenProperties

Eigenschaften sind eine natürliche Erweiterung der Felder.Properties are a natural extension of fields. Beide sind benannte Member mit zugeordneten Typen, und für den Zugriff auf Felder und Eigenschaften wird dieselbe Syntax verwendet.Both are named members with associated types, and the syntax for accessing fields and properties is the same. Im Gegensatz zu Feldern bezeichnen Eigenschaften jedoch keine Speicherorte.However, unlike fields, properties do not denote storage locations. Stattdessen verfügen Eigenschaften über Accessors zum Angeben der Anweisungen, die beim Lesen oder Schreiben ihrer Werte ausgeführt werden sollen.Instead, properties have accessors that specify the statements to be executed when their values are read or written.

Eine Eigenschaft wird wie ein Feld deklariert, mit der Ausnahme, get dass die Deklaration mit einem Accessor und/oder einem set Accessor endet, der { zwischen } den Trennzeichen und nicht mit einem Semikolon endet.A property is declared like a field, except that the declaration ends with a get accessor and/or a set accessor written between the delimiters { and } instead of ending in a semicolon. Eine Eigenschaft, die sowohl einen get -Accessor als set auch einen-Accessor aufweist, ist eine Eigenschaft mit Lese-/Schreibzugriff. eine Eigenschaft, die nur einen get -Accessor aufweist, ist eine schreibgeschützte Eigenschaft, und eine Eigenschaft mit nur einem set -Accessor ist eine schreibgeschützte Eigenschaft.A property that has both a get accessor and a set accessor is a read-write property, a property that has only a get accessor is a read-only property, and a property that has only a set accessor is a write-only property.

Ein get -Accessor entspricht einer Parameter losen Methode mit einem Rückgabewert des Eigenschaftentyps.A get accessor corresponds to a parameterless method with a return value of the property type. Wenn in einem Ausdruck get auf eine Eigenschaft verwiesen wird, wird der-Accessor der Eigenschaft aufgerufen, um den Wert der-Eigenschaft zu berechnen, außer als Ziel einer Zuweisung.Except as the target of an assignment, when a property is referenced in an expression, the get accessor of the property is invoked to compute the value of the property.

Ein set -Accessor entspricht einer Methode mit einem einzelnen Parameter mit value dem Namen und keinem Rückgabetyp.A set accessor corresponds to a method with a single parameter named value and no return type. Wenn als Ziel einer Zuweisung oder als Operand von oder ++ --auf eine Eigenschaft verwiesen wird, wird der set Accessor mit einem Argument aufgerufen, das den neuen Wert bereitstellt.When a property is referenced as the target of an assignment or as the operand of ++ or --, the set accessor is invoked with an argument that provides the new value.

Die List<T>-Klasse deklariert die beiden Eigenschaften „Count“ und „Capacity“, von denen die eine schreibgeschützt ist und die andere Lese- und Schreibzugriff besitzt.The List<T> class declares two properties, Count and Capacity, which are read-only and read-write, respectively. Es folgt ein Beispiel zur Verwendung dieser Eigenschaften.The following is an example of use of these properties.

List<string> names = new List<string>();
names.Capacity = 100;            // Invokes set accessor
int i = names.Count;             // Invokes get accessor
int j = names.Capacity;          // Invokes get accessor

Ähnlich wie bei Feldern und Methoden unterstützt C# sowohl Instanzeigenschaften als auch statische Eigenschaften.Similar to fields and methods, C# supports both instance properties and static properties. Statische Eigenschaften werden mit dem static -Modifizierer deklariert, und Instanzeigenschaften werden ohne Sie deklariert.Static properties are declared with the static modifier, and instance properties are declared without it.

Die Accessors einer Eigenschaft können virtuell sein.The accessor(s) of a property can be virtual. Wenn eine Eigenschaftendeklaration einen virtual-, abstract- oder override-Modifizierer enthält, wird dieser auf den Accessor der Eigenschaft angewendet.When a property declaration includes a virtual, abstract, or override modifier, it applies to the accessor(s) of the property.

IndexerIndexers

Ein Indexer ist ein Member, mit dem Objekte wie ein Array indiziert werden können.An indexer is a member that enables objects to be indexed in the same way as an array. Ein Indexer wird wie eine Eigenschaft deklariert, abgesehen davon, dass der Name des Members this ist, gefolgt von einer Parameterliste, die zwischen die Trennzeichen [ und ] geschrieben wird.An indexer is declared like a property except that the name of the member is this followed by a parameter list written between the delimiters [ and ]. Die Parameter stehen im Accessor des Indexers zur Verfügung.The parameters are available in the accessor(s) of the indexer. Ähnlich wie Eigenschaften können Indexer Lese-/Schreibzugriff besitzen, schreibgeschützt und lesegeschützt sein und virtuelle Accessors verwenden.Similar to properties, indexers can be read-write, read-only, and write-only, and the accessor(s) of an indexer can be virtual.

Die List-Klasse deklariert einen einzigen Indexer mit Lese-/Schreibzugriff, der einen int-Parameter akzeptiert.The List class declares a single read-write indexer that takes an int parameter. Der Indexer ermöglicht es, Instanzen von List mit int-Werten zu indizieren.The indexer makes it possible to index List instances with int values. Beispiel:For example

List<string> names = new List<string>();
names.Add("Liz");
names.Add("Martha");
names.Add("Beth");
for (int i = 0; i < names.Count; i++) {
    string s = names[i];
    names[i] = s.ToUpper();
}

Indexer können überladen werden, d.h. eine Klasse kann mehrere Indexer deklarieren, solange sich die Anzahl oder Typen ihrer Parameter unterscheiden.Indexers can be overloaded, meaning that a class can declare multiple indexers as long as the number or types of their parameters differ.

EreignisseEvents

Ein Ereignis ist ein Member, der es einer Klasse oder einem Objekt ermöglicht, Benachrichtigungen bereitzustellen.An event is a member that enables a class or object to provide notifications. Ein Ereignis wird wie ein Feld deklariert, mit der Ausnahme, dass event die Deklaration ein Schlüsselwort enthält und der Typ ein Delegattyp sein muss.An event is declared like a field except that the declaration includes an event keyword and the type must be a delegate type.

Innerhalb einer Klasse, die einen Ereignismember deklariert, verhält sich das Ereignis wie ein Feld des Delegattyps (vorausgesetzt, das Ereignis ist nicht abstrakt und deklariert keine Accessors).Within a class that declares an event member, the event behaves just like a field of a delegate type (provided the event is not abstract and does not declare accessors). Das Feld speichert einen Verweis auf einen Delegaten, der die Ereignishandler repräsentiert, die dem Ereignis hinzugefügt wurden.The field stores a reference to a delegate that represents the event handlers that have been added to the event. Wenn keine Ereignis Handles vorhanden sind, ist nulldas Feld.If no event handles are present, the field is null.

Die List<T>-Klasse deklariert einen einzigen Ereignismember namens Changed, der angibt, dass der Liste ein neues Element hinzugefügt wurde.The List<T> class declares a single event member called Changed, which indicates that a new item has been added to the list. Das Changed -Ereignis wird von der OnChanged virtuellen-Methode ausgelöst, die zuerst überprüft, ob null das Ereignis ist (d. h., dass keine Handler vorhanden sind).The Changed event is raised by the OnChanged virtual method, which first checks whether the event is null (meaning that no handlers are present). Das Auslösen eines Ereignisses entspricht exakt dem Aufrufen des Delegaten, der durch das Ereignis repräsentiert wird, es gibt deshalb keine besonderen Sprachkonstrukte zum Auslösen von Ereignissen.The notion of raising an event is precisely equivalent to invoking the delegate represented by the event—thus, there are no special language constructs for raising events.

Clients reagieren über Ereignishandler auf Ereignisse.Clients react to events through event handlers. Ereignishandler werden unter Verwendung des +=-Operators angefügt und mit dem -=-Operator entfernt.Event handlers are attached using the += operator and removed using the -= operator. Im folgenden Beispiel wird dem Changed-Ereignis von List<string> ein Ereignishandler hinzugefügt.The following example attaches an event handler to the Changed event of a List<string>.

using System;

class Test
{
    static int changeCount;

    static void ListChanged(object sender, EventArgs e) {
        changeCount++;
    }

    static void Main() {
        List<string> names = new List<string>();
        names.Changed += new EventHandler(ListChanged);
        names.Add("Liz");
        names.Add("Martha");
        names.Add("Beth");
        Console.WriteLine(changeCount);        // Outputs "3"
    }
}

In komplexeren Szenarien, in denen die zugrunde liegende Speicherung eines Ereignisses gesteuert werden soll, können in einer Ereignisdeklaration explizit die add- und remove-Accessors bereitgestellt werden. Diese ähneln in gewisser Weise dem set-Accessor einer Eigenschaft.For advanced scenarios where control of the underlying storage of an event is desired, an event declaration can explicitly provide add and remove accessors, which are somewhat similar to the set accessor of a property.

OperatorenOperators

Ein Operator ist ein Member, der die Bedeutung der Anwendung eines bestimmten Ausdrucksoperators auf Instanzen einer Klasse definiert.An operator is a member that defines the meaning of applying a particular expression operator to instances of a class. Es können drei Arten von Operatoren definiert werden: unäre Operatoren, binäre Operatoren und Konvertierungsoperatoren.Three kinds of operators can be defined: unary operators, binary operators, and conversion operators. Alle Operatoren müssen als public und static deklariert werden.All operators must be declared as public and static.

Die List<T>-Klasse deklariert zwei Operatoren, operator== und operator!=, und verleiht so Ausdrücken, die diese Operatoren auf List-Instanzen anwenden, eine neue Bedeutung.The List<T> class declares two operators, operator== and operator!=, and thus gives new meaning to expressions that apply those operators to List instances. Insbesondere definieren die Operatoren die Gleichheit von List<T> zwei-Instanzen, indem Sie die enthaltenen-Objekte Equals mithilfe ihrer Methoden vergleichen.Specifically, the operators define equality of two List<T> instances as comparing each of the contained objects using their Equals methods. Im folgenden Beispiel wird der ==-Operator verwendet, um zwei Instanzen von List<int> zu vergleichen.The following example uses the == operator to compare two List<int> instances.

using System;

class Test
{
    static void Main() {
        List<int> a = new List<int>();
        a.Add(1);
        a.Add(2);
        List<int> b = new List<int>();
        b.Add(1);
        b.Add(2);
        Console.WriteLine(a == b);        // Outputs "True"
        b.Add(3);
        Console.WriteLine(a == b);        // Outputs "False"
    }
}

Die erste Methode Console.WriteLine gibt True aus, weil die zwei Listen dieselbe Anzahl von Objekten mit denselben Werten in derselben Reihenfolge enthalten.The first Console.WriteLine outputs True because the two lists contain the same number of objects with the same values in the same order. Wenn List<T> nicht operator== definieren würde, würde die Ausgabe der ersten Console.WriteLine-Methode False lauten, weil a und b auf unterschiedliche List<int>-Instanzen verweisen.Had List<T> not defined operator==, the first Console.WriteLine would have output False because a and b reference different List<int> instances.

DestruktorenDestructors

Ein destrukturtor ist ein Member, der die erforderlichen Aktionen zum Zerstörung einer Instanz einer Klasse implementiert.A destructor is a member that implements the actions required to destruct an instance of a class. Dekonstruktoren können keine Parameter haben, Sie können keine Zugriffsmodifizierer aufweisen und können nicht explizit aufgerufen werden.Destructors cannot have parameters, they cannot have accessibility modifiers, and they cannot be invoked explicitly. Der Dekonstruktor für eine-Instanz wird automatisch während Garbage Collection aufgerufen.The destructor for an instance is invoked automatically during garbage collection.

Der Garbage Collector ist bei der Entscheidung unterstützt, wann Objekte gesammelt und dedeerdektoren ausgeführt werden sollen.The garbage collector is allowed wide latitude in deciding when to collect objects and run destructors. Insbesondere ist die zeitliche Steuerung der dekonstruktoraufrufe nicht deterministisch, und Dekonstruktoren können auf jedem beliebigen Thread ausgeführt werden.Specifically, the timing of destructor invocations is not deterministic, and destructors may be executed on any thread. Aus diesen und anderen Gründen sollten Klassen deserialisierungsgeräte nur implementieren, wenn keine anderen Lösungen möglich sind.For these and other reasons, classes should implement destructors only when no other solutions are feasible.

Die using-Anweisung bietet einen besseren Ansatz für die Objektzerstörung.The using statement provides a better approach to object destruction.

StrukturenStructs

Wie Klassen sind Strukturen Datenstrukturen, die Datenmember und Funktionsmember enthalten können, aber im Gegensatz zu Klassen sind Strukturen Werttypen und erfordern keine Heapzuordnung.Like classes, structs are data structures that can contain data members and function members, but unlike classes, structs are value types and do not require heap allocation. Eine Variable eines Strukturtyps speichert die Daten der Struktur direkt, während eine Variable eines Klassentyps einen Verweis auf ein dynamisch zugeordnetes Objekt speichert.A variable of a struct type directly stores the data of the struct, whereas a variable of a class type stores a reference to a dynamically allocated object. Strukturtypen unterstützen keine benutzerdefinierte Vererbung, und alle Strukturtypen erben implizit vom Typ object.Struct types do not support user-specified inheritance, and all struct types implicitly inherit from type object.

Strukturen sind besonders nützlich für kleine Datenstrukturen, die über Wertsemantik verfügen.Structs are particularly useful for small data structures that have value semantics. Komplexe Zahlen, Punkte in einem Koordinatensystem oder Schlüssel-Wert-Paare im Wörterbuch sind gute Beispiele für Strukturen.Complex numbers, points in a coordinate system, or key-value pairs in a dictionary are all good examples of structs. Die Verwendung von Strukturen statt Klassen für kleine Datenstrukturen kann bei der Anzahl der Speicherbelegungen, die eine Anwendung durchführt, einen großen Unterschied ausmachen.The use of structs rather than classes for small data structures can make a large difference in the number of memory allocations an application performs. Das folgende Programm erstellt und initialisiert z.B. ein Array aus 100 Punkten.For example, the following program creates and initializes an array of 100 points. Mit Point als implementierter Klasse werden 101 separate Objekte instanziiert – eines für das Array und jeweils eines für jedes der 100 Elemente.With Point implemented as a class, 101 separate objects are instantiated—one for the array and one each for the 100 elements.

class Point
{
    public int x, y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

class Test
{
    static void Main() {
        Point[] points = new Point[100];
        for (int i = 0; i < 100; i++) points[i] = new Point(i, i);
    }
}

Eine Alternative besteht darin, Point eine Struktur zu erstellen.An alternative is to make Point a struct.

struct Point
{
    public int x, y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

Jetzt wird nur ein Objekt instanziiert – für das Array – und die Point-Instanzen werden inline im Array gespeichert.Now, only one object is instantiated—the one for the array—and the Point instances are stored in-line in the array.

Strukturkonstruktoren werden mit dem neuen Operator new aufgerufen, doch das bedeutet nicht, dass der Arbeitsspeicher belegt wird.Struct constructors are invoked with the new operator, but that does not imply that memory is being allocated. Statt ein Objekt dynamisch zuzuordnen und einen Verweis darauf zurückzugeben, gibt ein Strukturkonstruktor einfach den Strukturwert selbst zurück (in der Regel in einen temporären Speicherort auf dem Stapel), und dieser Wert wird dann nach Bedarf kopiert.Instead of dynamically allocating an object and returning a reference to it, a struct constructor simply returns the struct value itself (typically in a temporary location on the stack), and this value is then copied as necessary.

Mit Klassen können zwei Variablen auf das gleiche Objekt verweisen, und so können an einer Variablen durchgeführte Vorgänge das Objekt beeinflussen, auf das die andere Variable verweist.With classes, it is possible for two variables to reference the same object and thus possible for operations on one variable to affect the object referenced by the other variable. Mit Strukturen besitzt jede Variable eine eigene Kopie der Daten, und es ist nicht möglich, dass an einer Variablen durchgeführte Vorgänge die andere beeinflussen.With structs, the variables each have their own copy of the data, and it is not possible for operations on one to affect the other. Beispielsweise ist die Ausgabe, die vom folgenden Code Fragment erzeugt wird, Point davon abhängig, ob eine Klasse oder eine Struktur ist.For example, the output produced by the following code fragment depends on whether Point is a class or a struct.

Point a = new Point(10, 10);
Point b = a;
a.x = 20;
Console.WriteLine(b.x);

Wenn Point eine Klasse ist, ist 20 die Ausgabe, a weil b und auf das gleiche Objekt verweisen.If Point is a class, the output is 20 because a and b reference the same object. Wenn Point eine Struktur ist, ist 10 die Ausgabe, b da durch die a Zuweisung von eine Kopie des Werts erstellt wird und diese Kopie von der nachfolgenden Zuweisung zu a.xnicht beeinträchtigt wird.If Point is a struct, the output is 10 because the assignment of a to b creates a copy of the value, and this copy is unaffected by the subsequent assignment to a.x.

Im vorherigen Beispiel werden zwei der Einschränkungen von Strukturen hervorgehoben.The previous example highlights two of the limitations of structs. Erstens ist das Kopieren einer gesamten Struktur in der Regel weniger effizient als das Kopieren eines Objektverweises, sodass Zuweisung und Wertparameterübergabe mit Strukturen aufwändiger sein kann als mit Verweistypen.First, copying an entire struct is typically less efficient than copying an object reference, so assignment and value parameter passing can be more expensive with structs than with reference types. Zweitens ist es mit Ausnahme der ref- und out-Parameter nicht möglich, Verweise auf Strukturen zu erstellen, was ihre Verwendung in einer Reihe von Situationen ausschließt.Second, except for ref and out parameters, it is not possible to create references to structs, which rules out their usage in a number of situations.

ArraysArrays

Ein Array ist eine Datenstruktur, die eine Anzahl von Variablen enthält, auf die über berechnete Indizes zugegriffen wird.An array is a data structure that contains a number of variables that are accessed through computed indices. Die im Array enthaltenen Variablen, auch Elemente des Arrays genannt, weisen alle denselben Typ auf. Dieser Typ wird als Elementtyp des Arrays bezeichnet.The variables contained in an array, also called the elements of the array, are all of the same type, and this type is called the element type of the array.

Arraytypen sind Verweistypen, und die Deklaration einer Arrayvariablen reserviert Speicher für einen Verweis auf eine Arrayinstanz.Array types are reference types, and the declaration of an array variable simply sets aside space for a reference to an array instance. Tatsächliche Array Instanzen werden zur Laufzeit dynamisch mithilfe des new -Operators erstellt.Actual array instances are created dynamically at run-time using the new operator. Der new -Vorgang gibt die Länge der neuen Array Instanz an, die dann für die Lebensdauer der-Instanz korrigiert wird.The new operation specifies the length of the new array instance, which is then fixed for the lifetime of the instance. Die Indizes der Arrayelemente reichen von 0 bis Length - 1.The indices of the elements of an array range from 0 to Length - 1. Der new-Operator initialisiert die Elemente eines Arrays automatisch mit ihren Standardwerten. Dieser lautet z.B. für alle numerischen Typen 0 und für alle Verweistypen null.The new operator automatically initializes the elements of an array to their default value, which, for example, is zero for all numeric types and null for all reference types.

Im folgenden Beispiel wird ein Array aus int-Elementen erstellt. Anschließend wird das Array initialisiert und die Inhalte des Arrays werden gedruckt.The following example creates an array of int elements, initializes the array, and prints out the contents of the array.

using System;

class Test
{
    static void Main() {
        int[] a = new int[10];
        for (int i = 0; i < a.Length; i++) {
            a[i] = i * i;
        }
        for (int i = 0; i < a.Length; i++) {
            Console.WriteLine("a[{0}] = {1}", i, a[i]);
        }
    }
}

Mit diesem Beispiel wird ein eindimensionales Array erstellt und verwendet.This example creates and operates on a single-dimensional array. C# unterstützt auch mehrdimensionale Arrays.C# also supports multi-dimensional arrays. Die Anzahl von Dimensionen eines Arraytyps, auch als Rang des Arraytyps bezeichnet, ist 1 plus die Anzahl von Kommas, die innerhalb der eckigen Klammern des Arraytyps angegeben ist.The number of dimensions of an array type, also known as the rank of the array type, is one plus the number of commas written between the square brackets of the array type. Im folgenden Beispiel wird ein eindimensionales, ein zweidimensionales und ein dreidimensionales Array zugeordnet.The following example allocates a one-dimensional, a two-dimensional, and a three-dimensional array.

int[] a1 = new int[10];
int[,] a2 = new int[10, 5];
int[,,] a3 = new int[10, 5, 2];

Das a1-Array enthält 10 Elemente, das a2-Array umfasst 50 (10 × 5) Elemente, und das a3-Array enthält 100 (10 × 5 × 2) Elemente.The a1 array contains 10 elements, the a2 array contains 50 (10 × 5) elements, and the a3 array contains 100 (10 × 5 × 2) elements.

Ein Array kann einen beliebigen Elementtyp verwenden, einschließlich eines Arraytyps.The element type of an array can be any type, including an array type. Ein Array mit Elementen eines Arraytyps wird auch als verzweigtes Array bezeichnet, weil die Länge der Elementarrays nicht identisch sein muss.An array with elements of an array type is sometimes called a jagged array because the lengths of the element arrays do not all have to be the same. Im folgenden Beispiel wird ein Array aus int-Arrays zugewiesen:The following example allocates an array of arrays of int:

int[][] a = new int[3][];
a[0] = new int[10];
a[1] = new int[5];
a[2] = new int[20];

In der ersten Zeile wird ein Array mit drei Elementen erstellt, das jeweils den Typ int[] und einen Anfangswert von null aufweist.The first line creates an array with three elements, each of type int[] and each with an initial value of null. In den folgenden Zeilen werden die drei Elemente mit Verweisen auf einzelne Arrayinstanzen unterschiedlicher Länge initialisiert.The subsequent lines then initialize the three elements with references to individual array instances of varying lengths.

Der new -Operator ermöglicht das Angeben der Anfangswerte der Array Elemente mithilfe eines { Arrayinitialisierers, bei dem es sich um eine Liste von Ausdrücken handelt, die }zwischen den Trennzeichen und geschrieben werden.The new operator permits the initial values of the array elements to be specified using an array initializer, which is a list of expressions written between the delimiters { and }. Mit dem folgenden Beispiel wird ein int[] mit drei Elementen zugewiesen und initialisiert.The following example allocates and initializes an int[] with three elements.

int[] a = new int[] {1, 2, 3};

Beachten Sie, dass die Länge des Arrays von der Anzahl von Ausdrücken zwischen { und }abgeleitet wird.Note that the length of the array is inferred from the number of expressions between { and }. Deklarationen lokaler Variablen und Felder können weiter verkürzt werden, sodass der Arraytyp nicht erneut aufgeführt werden muss.Local variable and field declarations can be shortened further such that the array type does not have to be restated.

int[] a = {1, 2, 3};

Die zwei vorherigen Beispiele entsprechen dem folgenden:Both of the previous examples are equivalent to the following:

int[] t = new int[3];
t[0] = 1;
t[1] = 2;
t[2] = 3;
int[] a = t;

SchnittstellenInterfaces

Eine Schnittstelle definiert einen Vertrag, der von Klassen und Strukturen implementiert werden kann.An interface defines a contract that can be implemented by classes and structs. Eine Schnittstelle kann Methoden, Eigenschaften, Ereignisse und Indexer enthalten.An interface can contain methods, properties, events, and indexers. Eine Schnittstelle stellt keine Implementierungen der von ihr definierten Member bereit. Sie gibt lediglich die Member an, die von Klassen oder Strukturen bereitgestellt werden müssen, die die Schnittstelle implementieren.An interface does not provide implementations of the members it defines—it merely specifies the members that must be supplied by classes or structs that implement the interface.

Schnittstellen können Mehrfachvererbung einsetzen.Interfaces may employ multiple inheritance. Im folgenden Beispiel erbt die Schnittstelle IComboBox sowohl von ITextBox als auch IListBox.In the following example, the interface IComboBox inherits from both ITextBox and IListBox.

interface IControl
{
    void Paint();
}

interface ITextBox: IControl
{
    void SetText(string text);
}

interface IListBox: IControl
{
    void SetItems(string[] items);
}

interface IComboBox: ITextBox, IListBox {}

Klassen und Strukturen können mehrere Schnittstellen implementieren.Classes and structs can implement multiple interfaces. Im folgenden Beispiel implementiert die Klasse EditBox sowohl IControl als auch IDataBound.In the following example, the class EditBox implements both IControl and IDataBound.

interface IDataBound
{
    void Bind(Binder b);
}

public class EditBox: IControl, IDataBound
{
    public void Paint() {...}
    public void Bind(Binder b) {...}
}

Wenn eine Klasse oder Struktur eine bestimmte Schnittstelle implementiert, können Instanzen dieser Klasse oder Struktur implizit in diesen Schnittstellentyp konvertiert werden.When a class or struct implements a particular interface, instances of that class or struct can be implicitly converted to that interface type. Beispiel:For example

EditBox editBox = new EditBox();
IControl control = editBox;
IDataBound dataBound = editBox;

In Fällen, in denen nicht bekannt ist, dass eine Instanz eine bestimmte Schnittstelle implementiert, können dynamische Typumwandlungen verwendet werden.In cases where an instance is not statically known to implement a particular interface, dynamic type casts can be used. Die folgenden-Anweisungen verwenden z. b. dynamische Typumwandlungen, um IControl die IDataBound -und-Schnittstellen Implementierungen eines Objekts abzurufen.For example, the following statements use dynamic type casts to obtain an object's IControl and IDataBound interface implementations. Da der tatsächliche Objekttyp ist EditBox, sind die Umwandlungen erfolgreich.Because the actual type of the object is EditBox, the casts succeed.

object obj = new EditBox();
IControl control = (IControl)obj;
IDataBound dataBound = (IDataBound)obj;

In der vorherigen EditBox Klasse werden die Paint -Methode aus IControl der-Schnitt Bind Stelle und die IDataBound -Methode aus der public -Schnittstelle mithilfe von Membern implementiert.In the previous EditBox class, the Paint method from the IControl interface and the Bind method from the IDataBound interface are implemented using public members. C#unterstützt auch explizite Implementierungenvon Schnittstellenmembern, wobei die Klasse oder Struktur das Erstellen publicder Member vermeiden kann.C# also supports explicit interface member implementations, using which the class or struct can avoid making the members public. Eine explizite Implementierung eines Schnittstellenmembers wird mit dem vollqualifizierten Namen des Schnittstellenmembers geschrieben.An explicit interface member implementation is written using the fully qualified interface member name. Die EditBox-Klasse könnte z.B. die IControl.Paint- und IDataBound.Bind-Methode wie folgt über explizite Implementierungen eines Schnittstellenmembers implementieren.For example, the EditBox class could implement the IControl.Paint and IDataBound.Bind methods using explicit interface member implementations as follows.

public class EditBox: IControl, IDataBound
{
    void IControl.Paint() {...}
    void IDataBound.Bind(Binder b) {...}
}

Der Zugriff auf explizite Schnittstellenmember kann nur über den Schnittstellentyp erfolgen.Explicit interface members can only be accessed via the interface type. Beispielsweise kann die Implementierung von IControl.Paint , die von der EditBox vorherigen-Klasse bereitgestellt wird, nur aufgerufen EditBox werden, indem IControl zuerst der Verweis in den Schnittstellentyp umgerechnet wird.For example, the implementation of IControl.Paint provided by the previous EditBox class can only be invoked by first converting the EditBox reference to the IControl interface type.

EditBox editBox = new EditBox();
editBox.Paint();                        // Error, no such method
IControl control = editBox;
control.Paint();                        // Ok

EnumerationenEnums

Ein Enumerationstyp ist ein eindeutiger Werttyp mit einem Satz benannter Konstanten.An enum type is a distinct value type with a set of named constants. Im folgenden Beispiel wird ein Enumerationstyp mit dem Color Namen mit den drei Konstanten RedWerten Green,, Blueund deklariert und verwendet.The following example declares and uses an enum type named Color with three constant values, Red, Green, and Blue.

using System;

enum Color
{
    Red,
    Green,
    Blue
}

class Test
{
    static void PrintColor(Color color) {
        switch (color) {
            case Color.Red:
                Console.WriteLine("Red");
                break;
            case Color.Green:
                Console.WriteLine("Green");
                break;
            case Color.Blue:
                Console.WriteLine("Blue");
                break;
            default:
                Console.WriteLine("Unknown color");
                break;
        }
    }

    static void Main() {
        Color c = Color.Red;
        PrintColor(c);
        PrintColor(Color.Blue);
    }
}

Jeder Aufzählungstyp verfügt über einen entsprechenden ganzzahligen Typ, der als zugrunde liegenden Typ des Aufzählungs Typs bezeichnet wird.Each enum type has a corresponding integral type called the underlying type of the enum type. Ein Aufzählungs Typ, der den zugrunde liegenden Typ nicht explizit deklariert, verfügt über inteinen zugrunde liegenden Typ von.An enum type that does not explicitly declare an underlying type has an underlying type of int. Das Speicherformat eines Enumerationstyps und der Bereich möglicher Werte werden durch den zugrunde liegenden Typ bestimmt.An enum type's storage format and range of possible values are determined by its underlying type. Der Satz von Werten, der von einem Enumerationstyp übernommen werden kann, wird nicht durch seine Enumerationsmember eingeschränkt.The set of values that an enum type can take on is not limited by its enum members. Insbesondere kann jeder Wert des zugrunde liegenden Typs einer Enumeration in den Enumerationstyp umgewandelt werden und ist ein eindeutiger gültiger Wert dieses Enumerationstyps.In particular, any value of the underlying type of an enum can be cast to the enum type and is a distinct valid value of that enum type.

Im folgenden Beispiel wird ein Aufzählungstyp Alignment mit dem Namen mit dem sbytezugrunde liegenden Typ deklariert.The following example declares an enum type named Alignment with an underlying type of sbyte.

enum Alignment: sbyte
{
    Left = -1,
    Center = 0,
    Right = 1
}

Wie im vorherigen Beispiel gezeigt, kann eine Enumerationsmember-Deklaration einen konstanten Ausdruck enthalten, der den Wert des Members angibt.As shown by the previous example, an enum member declaration can include a constant expression that specifies the value of the member. Der Konstante Wert für jedes Enumerationsmember muss im Bereich des zugrunde liegenden Typs der Enumeration liegen.The constant value for each enum member must be in the range of the underlying type of the enum. Wenn eine Enumerationsmember-Deklaration nicht explizit einen Wert angibt, erhält der Member den Wert 0 (null), wenn es sich um den ersten Member im Enumerationstyp handelt, oder den Wert des texthalen vorangehenden Enumerationsmembers plus eins.When an enum member declaration does not explicitly specify a value, the member is given the value zero (if it is the first member in the enum type) or the value of the textually preceding enum member plus one.

Enumerationswerte können mithilfe von Typumwandlungen in ganzzahlige Werte und umgekehrt konvertiert werden.Enum values can be converted to integral values and vice versa using type casts. Beispiel:For example

int i = (int)Color.Blue;        // int i = 2;
Color c = (Color)2;             // Color c = Color.Blue;

Der Standardwert eines beliebigen Enumerationstyps ist der ganzzahlige Wert NULL, der in den Enumerationstyp konvertiert wird.The default value of any enum type is the integral value zero converted to the enum type. In Fällen, in denen Variablen automatisch mit einem Standardwert initialisiert werden, ist dies der Wert, der Variablen von Enumerationstypen zugewiesen wird.In cases where variables are automatically initialized to a default value, this is the value given to variables of enum types. Damit der Standardwert eines Enumerationstyps leicht verfügbar ist, wird das Literale 0 implizit in einen beliebigen Enumerationstyp konvertiert.In order for the default value of an enum type to be easily available, the literal 0 implicitly converts to any enum type. Daher ist Folgendes zugelassen.Thus, the following is permitted.

Color c = 0;

DelegatenDelegates

Ein Delegattyp stellt Verweise auf Methoden mit einer bestimmten Parameterliste und dem Rückgabetyp dar.A delegate type represents references to methods with a particular parameter list and return type. Delegate ermöglichen die Behandlung von Methoden als Entitäten, die Variablen zugewiesen und als Parameter übergeben werden können.Delegates make it possible to treat methods as entities that can be assigned to variables and passed as parameters. Delegate ähneln dem Konzept von Funktionszeigern, die Sie in einigen anderen Sprachen finden. Im Gegensatz zu Funktionszeigern sind Delegate allerdings objektorientiert und typsicher.Delegates are similar to the concept of function pointers found in some other languages, but unlike function pointers, delegates are object-oriented and type-safe.

Im folgenden Beispiel wird ein Delegattyp namens Function deklariert und verwendet.The following example declares and uses a delegate type named Function.

using System;

delegate double Function(double x);

class Multiplier
{
    double factor;

    public Multiplier(double factor) {
        this.factor = factor;
    }

    public double Multiply(double x) {
        return x * factor;
    }
}

class Test
{
    static double Square(double x) {
        return x * x;
    }

    static double[] Apply(double[] a, Function f) {
        double[] result = new double[a.Length];
        for (int i = 0; i < a.Length; i++) result[i] = f(a[i]);
        return result;
    }

    static void Main() {
        double[] a = {0.0, 0.5, 1.0};
        double[] squares = Apply(a, Square);
        double[] sines = Apply(a, Math.Sin);
        Multiplier m = new Multiplier(2.0);
        double[] doubles =  Apply(a, m.Multiply);
    }
}

Eine Instanz des Delegattyps Function kann auf jede Methode verweisen, die ein double-Argument und einen double-Wert akzeptiert.An instance of the Function delegate type can reference any method that takes a double argument and returns a double value. Die Apply -Methode wendet eine Function angegebene auf die Elemente einer double[]an und gibt double[] ein mit den Ergebnissen zurück.The Apply method applies a given Function to the elements of a double[], returning a double[] with the results. In der Main-Methode wird Apply verwendet, um drei verschiedene Funktionen auf ein double[] anzuwenden.In the Main method, Apply is used to apply three different functions to a double[].

Ein Delegat kann entweder auf eine statische Methode verweisen (z.B. Square oder Math.Sin im vorherigen Beispiel) oder eine Instanzmethode (z.B. m.Multiply im vorherigen Beispiel).A delegate can reference either a static method (such as Square or Math.Sin in the previous example) or an instance method (such as m.Multiply in the previous example). Ein Delegat, der auf eine Instanzmethode verweist, verweist auch auf ein bestimmtes Objekt, und wenn die Instanzmethode durch den Delegaten aufgerufen wird, wird das Objekt this im Aufruf.A delegate that references an instance method also references a particular object, and when the instance method is invoked through the delegate, that object becomes this in the invocation.

Delegaten können auch mit anonymen Funktionen erstellt werden, die dynamisch erstellte „Inlinemethoden“ sind.Delegates can also be created using anonymous functions, which are "inline methods" that are created on the fly. Anonyme Funktionen können die lokalen Variablen der umgebenden Methoden sehen.Anonymous functions can see the local variables of the surrounding methods. Daher kann das obige Multiplikator-Beispiel einfacher geschrieben werden, ohne eine Multiplier Klasse zu verwenden:Thus, the multiplier example above can be written more easily without using a Multiplier class:

double[] doubles =  Apply(a, (double x) => x * 2.0);

Eine interessante und nützliche Eigenschaft eines Delegaten ist, dass er die Klasse der Methode, auf die er verweist, nicht kennt oder sie ignoriert; wichtig ist nur, dass die referenzierte Methode die gleichen Parameter und den gleichen Rückgabetyp hat wie der Delegat.An interesting and useful property of a delegate is that it does not know or care about the class of the method it references; all that matters is that the referenced method has the same parameters and return type as the delegate.

AttributeAttributes

Typen, Member und andere Entitäten in einem C#-Programm unterstützen Modifizierer, die bestimmte Aspekte ihres Verhaltens steuern.Types, members, and other entities in a C# program support modifiers that control certain aspects of their behavior. Der Zugriff auf eine Methode wird beispielsweise mithilfe der Modifizierer public, protected, internal und private kontrolliert.For example, the accessibility of a method is controlled using the public, protected, internal, and private modifiers. C# generalisiert diese Funktionalität, indem benutzerdefinierte Typen deklarativer Informationen an eine Programmentität angefügt und zur Laufzeit abgerufen werden können.C# generalizes this capability such that user-defined types of declarative information can be attached to program entities and retrieved at run-time. Programm geben diese zusätzlichen deklarativen Informationen durch das Definieren und Verwenden von Attributen an.Programs specify this additional declarative information by defining and using attributes.

Im folgenden Beispiel wird ein HelpAttribute-Attribut deklariert, dass in Programmentitäten platziert werden kann, um Links zur zugehörigen Dokumentation bereitzustellen.The following example declares a HelpAttribute attribute that can be placed on program entities to provide links to their associated documentation.

using System;

public class HelpAttribute: Attribute
{
    string url;
    string topic;

    public HelpAttribute(string url) {
        this.url = url;
    }

    public string Url {
        get { return url; }
    }

    public string Topic {
        get { return topic; }
        set { topic = value; }
    }
}

Alle Attribut Klassen werden von der System.Attribute Basisklasse abgeleitet, die von der .NET Framework bereitgestellt wird.All attribute classes derive from the System.Attribute base class provided by the .NET Framework. Attribute können durch Angabe ihres Namens angewendet werden, zusammen mit beliebigen Argumenten. Diese müssen in eckigen Klammern genau vor der zugehörigen Deklaration eingefügt werden.Attributes can be applied by giving their name, along with any arguments, inside square brackets just before the associated declaration. Wenn der Name eines Attributs auf Attributeendet, kann dieser Teil des Namens ausgelassen werden, wenn auf das Attribut verwiesen wird.If an attribute's name ends in Attribute, that part of the name can be omitted when the attribute is referenced. Beispielsweise kann das HelpAttribute-Attribut wie folgt verwendet werden.For example, the HelpAttribute attribute can be used as follows.

[Help("http://msdn.microsoft.com/.../MyClass.htm")]
public class Widget
{
    [Help("http://msdn.microsoft.com/.../MyClass.htm", Topic = "Display")]
    public void Display(string text) {}
}

In diesem Beispiel wird HelpAttribute ein an Widget die-Klasse HelpAttribute und ein Display anderes an die-Methode in der-Klasse angefügt.This example attaches a HelpAttribute to the Widget class and another HelpAttribute to the Display method in the class. Die öffentlichen Konstruktoren einer Attributklasse steuern die Informationen, die beim Anfügen des Attributs an eine Programmentität angegeben werden müssen.The public constructors of an attribute class control the information that must be provided when the attribute is attached to a program entity. Zusätzliche Informationen können angegeben werden, indem auf öffentliche Eigenschaften mit Lese-/Schreibzugriff der Attributklasse verwiesen wird (z.B. wie der obige Verweis auf die Topic-Eigenschaft).Additional information can be provided by referencing public read-write properties of the attribute class (such as the reference to the Topic property previously).

Im folgenden Beispiel wird gezeigt, wie Attributinformationen für eine bestimmte Programm Entität zur Laufzeit mithilfe von Reflektion abgerufen werden können.The following example shows how attribute information for a given program entity can be retrieved at run-time using reflection.

using System;
using System.Reflection;

class Test
{
    static void ShowHelp(MemberInfo member) {
        HelpAttribute a = Attribute.GetCustomAttribute(member,
            typeof(HelpAttribute)) as HelpAttribute;
        if (a == null) {
            Console.WriteLine("No help for {0}", member);
        }
        else {
            Console.WriteLine("Help for {0}:", member);
            Console.WriteLine("  Url={0}, Topic={1}", a.Url, a.Topic);
        }
    }

    static void Main() {
        ShowHelp(typeof(Widget));
        ShowHelp(typeof(Widget).GetMethod("Display"));
    }
}

Wenn per Reflektion ein bestimmtes Attribut angefordert wird, wird der Konstruktor für die Attributklasse mit den in der Programmquelle angegebenen Informationen aufgerufen, und die resultierende Attributinstanz wird zurückgegeben.When a particular attribute is requested through reflection, the constructor for the attribute class is invoked with the information provided in the program source, and the resulting attribute instance is returned. Wenn zusätzliche Informationen über Eigenschaften bereitgestellt wurden, werden diese Eigenschaften auf die vorgegebenen Werte festgelegt, bevor die Attributinstanz zurückgegeben wird.If additional information was provided through properties, those properties are set to the given values before the attribute instance is returned.