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 Wurzeln in der Sprachen C und C, C++ und Java-Programmierer sofort vertraut sein.C# has its roots in the C family of languages and will be immediately familiar to C, C++, and Java programmers. C# ist durch ECMA-International als standardisiert die ECMA-334 standard und ISO/IEC als die ISO/IEC 23270 standard.C# is standardized by ECMA International as the ECMA-334 standard and by ISO/IEC as the ISO/IEC 23270 standard. Von Microsoft c#-Compiler für .NET Framework ist keine entsprechende Implementierung dieser beiden dieser 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# bietet Sprachkonstrukte zur direkten Unterstützung für diese Konzepte, wodurch c# zu einer sehr natürlichen Sprache, in denen zum Erstellen und Verwenden der Software-Komponenten.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: Die automatische speicherbereinigung von nicht verwendeten Objekte belegten Arbeitsspeicher automatisch freigibt Ausnahmebehandlung bietet einen strukturierten und erweiterbaren Ansatz für die fehlererkennung und Wiederherstellung und die typsichere Aufbau der Sprache macht es unmöglich, nicht initialisierte Variablen gelesen werden soll. Geben Sie zum Indizieren Umwandlungen Arrays über die Grenzen oder führen Sie deaktiviert.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, dass c#-Programmen und Bibliotheken im Laufe der Zeit kompatibel weiterentwickelt werden können, wurde viel Bedeutung für platziert versionsverwaltung # Entwurf.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 der C#des Entwurfs, der direkt von Überlegungen bei der Versionskontrolle beeinflusst wurden, gehören die separaten virtual und override Modifizierer, die Regeln für die überladungsauflösung und die Unterstützung für explizite Schnittstellenmember-Deklarationen.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 verbleibenden Teil dieses Kapitels wird beschrieben, die wesentlichen Funktionen von c#-Sprache.The rest of this chapter describes the essential features of the C# language. Obwohl es sich bei spätere Kapiteln detailorientiertheit und manchmal mathematischen Regeln und Ausnahmen zu beschreiben, wurde in diesem Kapitel für Klarheit und Übersichtlichkeit zu Lasten der Vollständigkeit.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. Ziel ist für eine Einführung in die Sprache des Readers bereit, die das Schreiben von frühen Programme und das Lesen der späteren Kapiteln erleichtern wird.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. Unter der Annahme, dass das Programm "Hello, World" in der Datei gespeichert wird hello.cs, das Programm kompiliert werden kann, mit dem Microsoft C#-Compiler, die über die BefehlszeileAssuming 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

erzeugt eine ausführbare Assembly mit dem Namen hello.exe.which produces an executable assembly named hello.exe. Die Ausgabe von dieser Anwendung erstellt wird, wenn er ausgeführt wirdThe 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 deklariert, mit der static Modifizierer.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 der .NET Framework-Klassenbibliotheken bereitgestellt, die standardmäßig vom Microsoft C#-Compiler automatisch verwiesen wird.This class is provided by the .NET Framework class libraries, which, by default, are automatically referenced by the Microsoft C# compiler. Beachten Sie, dass c# selbst keine separate Laufzeit-Bibliothek.Note that C# itself does not have a separate runtime library. Stattdessen ist .NET Framework die Runtime-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 müssen in der Regel die Dateierweiterung .exe oder .dll, abhängig davon, ob sie implementieren Anwendungen oder Bibliotheken.Assemblies typically have the file extension .exe or .dll, depending on whether they implement applications or libraries.

Im 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 namens Stack in einem Namespace namens Acme.Collections.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 symbolischen 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 in der Datei gespeichert ist test.csbei test.cs kompiliert wurde, die acme.dll Assembly kann verwiesen werden, mithilfe des Compilers /r Option: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, Strukturtypen, und auf NULL festlegbare Typen, und C#des Verweistypen sind weiter unterteilt in Klassentypen, Schnittstellentypen, Arraytypen, und 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.

Die folgende Tabelle enthält eine Übersicht über C#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 im Format 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.

Zeigen Sie die beiden floating-Typen, float und double, werden mit der 32-Bit mit einfacher Genauigkeit und 64-Bit-Gleitkommazahl mit doppelter Genauigkeit IEEE 754-Formate 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#die bool Typ dient zur Darstellung boolescher Werte – Werte, die entweder true oder false.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.

Die folgende Tabelle enthält C#der numerischen Typen.The following table summarizes C#'s numeric types.

KategorieCategory BitsBits TypeType Bereich/der gleichen GenauigkeitRange/Precision
Ganzzahlig mit VorzeichenSigned integral 88 sbyte -128...127-128...127
1616 short -32,768...32,767-32,768...32,767
3232 int -2,147,483,648...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, Genauigkeit von 7 Stellen1.5 × 10^−45 to 3.4 × 10^38, 7-digit precision
6464 double 5,0 × 10 ^-324 bis 1,7 × 10 ^ 308, Genauigkeit von 15 Stellen5.0 × 10^−324 to 1.7 × 10^308, 15-digit precision
DecimalDecimal 128128 decimal 1.0 × 10 ^-28 7,9 × 10 ^ 28, 28 Stellen 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 C#der Kategorien von Typen sind Benutzerdefinierbar: Klasse Typen, 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, da es sich um 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 Gegensatz zu Klassen, Strukturen sind allerdings Werttypen und erfordern keine Heapzuordnung.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 benannter Satz öffentlicher Funktionsmember.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 Basisschnittstellen 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 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.

Klasse, Struktur, Schnittstellen- und Delegattypen-Typen unterstützen generische Typen, 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 eigenständiger Typ mit benannter Konstanten.An enum type is a distinct type with named constants. Jeder Enumerationstyp hat einen zugrunde liegenden Typ, der eine der acht ganzzahligen Typen sein muss.Every enum type has an underlying type, which must be one of the eight integral types. Der Satz von Werten eines Enumerationstyps ist der 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. Z. B. int[] ist ein eindimensionales Array von int, int[,] wird ein zweidimensionales Array von int, und int[][] ist ein eindimensionales Array des 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.

Auf NULL festlegbare Typen auch keine 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 NULL-Werte T wird es ein entsprechenden nullable-Typ T?, die einen zusätzlichen Wert enthalten kann null.For each non-nullable value type T there is a corresponding nullable type T?, which can hold an additional value null. Z. B. int? ist ein Typ, der alle 32-Bit-Ganzzahlwert oder den Wert aufnehmen kann null.For instance, int? is a type that can hold any 32 bit integer or the value null.

C#Typsystem ist dahingehend vereinheitlicht, dass 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 Sie Ausführung Boxing und unboxing Vorgänge.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 der Wert eines Werttyps in den Typ konvertiert wird object, eine Objektinstanz, die auch "Box" genannte wird zum Speichern des Werts zugeordnet, und der Wert wird in diese Box 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. Im Gegensatz dazu, wann ein object Verweis auf einen Werttyp umgewandelt wird, wird eine Überprüfung durchgeführt, die das referenzierte Objekt ein Feld des korrekten Datentyps ist und, wenn die Überprüfung erfolgreich ist, wird der Wert in das 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#der unified Type System bedeutet, dass Werttypen "bei Bedarf." Objekte werden könnenC#'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 hat einen Typ, der bestimmt, welche Werte können in der Variablen gespeichert wird, wie in der folgenden Tabelle gezeigt.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ögliche 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 einen Wert genau dieses TypsA null value or a value of that exact type
object Ein null-Verweis, einen Verweis auf ein Objekt von einem beliebigen Verweistyp oder ein Verweis auf einen geschachtelten Wert eines beliebigen WerttypsA 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, einen Verweis auf eine Instanz dieses Klassentyps oder ein Verweis auf eine Instanz einer Klasse abgeleitet werden, von diesem KlassentypA 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, einen Verweis auf eine Instanz eines Klassentyps, der diesen Schnittstellentyp implementiert oder einen Verweis auf einen geschachtelten Wert eines Werttyps, der diesen Schnittstellentyp implementiertA 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, einen Verweis auf eine Instanz dieses Arraytyps oder ein Verweis auf eine Instanz von eines kompatiblen ArraytypsA 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 einen Verweis auf eine Instanz dieses DelegattypsA 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.

Die folgende Tabelle enthält C#Operatoren, die Operatorkategorien gemäß der Rangfolge von der höchsten zur niedrigsten Ebene auflisten.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 Expression (Ausdruck)Expression 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, wenn x ist trueEvaluates y only if x is true
Bedingtes ORConditional OR x || y Wertet y nur, wenn x ist falseEvaluates y only if x is false
NULL-SammeloperatorNull coalescing x ?? y Ergibt y Wenn x ist nullzu x andernfallsEvaluates 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 Zusammengesetzte Zuweisung; Operatoren werden unterstützt *= /= %= += -= <<= >>= &= ^= |=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, enthalten Methodenaufrufe, objektzuordnungen mit dem new Operator, Zuweisungen mit = und die Verbundzuweisungsoperatoren, inkrementier- und dekrementiervorgänge-Vorgänge, die unter Verwendung der ++und -- Operatoren und await-Ausdrücken.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.

Iterationsanweisungen 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 und unchecked Anweisungen werden verwendet, um den Kontext für arithmetische Operationen für ganzzahlige Typen und Konvertierungen für die überlaufüberprüfung 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 AnweisungBelow 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 von lokalen KonstantenLocal constant declaration

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

AusdrucksanweisungExpression 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);
    }
}

throw und 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!");
    }
}

checked und 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. Die folgenden Anweisungen erstellen Sie zwei Point Objekte und Verweise auf diese Objekte in zwei Variablen zu speichern: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.

MemberMember 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 BedeutungMeaning
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. Der Typparameter können die im Text der Klassendeklarationen verwendet werden, um der 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 zum Akzeptieren von Typparametern deklariert ist, wird einen Typ generische Klasse aufgerufen.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 den Typargumente angegeben wurden, wie z. B. Pair<int,string> oben einen konstruierten Typ aufgerufen wird.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, mit Ausnahme von der Instanz und statische Konstruktoren und Destruktoren der Basisklasse enthält.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 mit einer Klasse oder eine Instanz einer Klasse zugeordnet ist.A field is a variable that is associated with a class or with an instance of a class.

Ein Feld deklariert, mit der static -Modifizierer definiert eine 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 deklariert, ohne die static -Modifizierer definiert eine Instanzenfeld.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. Zuweisung zu einem readonly Feld kann nur als Teil einer Deklaration oder in einem Konstruktor derselben Klasse auftreten.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 Parameter, die darstellen, Werte oder Variablenverweise an die Methode übergeben, und ein Rückgabetyp, der angibt, dass der Typ des Werts berechnet und zurückgegeben, indem die Methode.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 Methode ist void , 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 und WriteLine Methoden der System.Console -Klasse sind gute Beispiele für die Verwendung eines Parameterarrays.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 Methodenkörper gibt an, die Anweisungen ausgeführt werden, wenn die Methode aufgerufen wird.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 zurückgeben von nicht -void, return -Anweisungen müssen einen Ausdruck, der den Rückgabewert berechnet enthalten.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 deklariert, mit einem static Modifizierer ist ein 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 deklariert werden, ohne eine static Modifizierer ist ein 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.

Das folgende Beispiel zeigt die Verwendung der Entity Klasse.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 gilt eine nicht virtuellen Methode.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 enthält ein override Modifizierer, die Methode überschreibt eine geerbte virtuelle Methode mit der gleichen 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.

Ein abstrakte Methode ist eine virtuelle Methode ohne Implementierung.An abstract method is a virtual method with no implementation. Eine abstrakte Methode ist deklariert, mit der abstract Modifizierer und darf nur in einer Klasse, die auch deklariert wird abstract.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. (Dieser Vorgang ähnelt, aber nicht zu verwechseln mit die ausdrucksbaumstrukturtypen, das in eingeführte ausdrucksbaumstrukturtypen).(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, die als Argument akzeptiert eine Hashtable , 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, was bedeutet, dass nicht abstrakte abgeleitete Klassen ü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. Ein VariableReferencedie Implementierung sieht nach dem Variablennamen in der Hashtabelle und gibt den Ergebniswert 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 wird beschrieben, die andere Arten von Funktionsmembern von c# unterstützt: Konstruktoren, Eigenschaften, Indexer, Ereignisse, Operatoren und Destruktoren.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 namens List<T>, die eine wachsende Liste von Objekten 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 verwendet enthält eine static Modifizierer verwenden, wird einen statischen 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 zwei List<string> Instanzen, indem Sie die Konstruktoren der List Klasse.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, außer dass die Deklaration mit endet eine get Accessor und/oder einen set Accessor, die zwischen den Trennzeichen { und } statt 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 beides aufweist eine get Accessor und einen set -Accessor ist eine Lese-/ Schreibzugriff-Eigenschaft, eine Eigenschaft, die nur eine get -Accessor ist eine schreibgeschützte Eigenschaft, und ein Eigenschaft, die nur eine set -Accessor ist eine lesegeschü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 Methode ohne Parameter mit einem Rückgabewert des Eigenschaftstyps.A get accessor corresponds to a parameterless method with a return value of the property type. Eine Eigenschaft in einem Ausdruck verwiesen wird, wird als Ziel einer Zuweisung, außer die get -Accessor der Eigenschaft wird aufgerufen, um den Wert der Eigenschaft zu berechnen.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 einzigen Parameter, die mit dem Namen value und keinen Rückgabewert.A set accessor corresponds to a method with a single parameter named value and no return type. Wenn eine Eigenschaft verwiesen wird, als das Ziel einer Zuweisung oder als Operand ++ oder --, set -Accessor wird aufgerufen, mit der ein Argument, 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 deklariert, mit der static Modifizierer und Instanzeigenschaften werden ohne ihn 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, mit dem Unterschied, dass der Name des Members this gefolgt von einer Parameterliste, die zwischen den Trennzeichen [ und ].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 dem Unterschied, dass die Deklaration enthält eine event -Schlüsselwort und der Typ müssen ein Delegattyp sein.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 Handles für ein Ereignis vorhanden sind, wird das Feld null.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. Die Changed Ereignis wird ausgelöst, durch die OnChanged virtuelle Methode, die zunächst prüft, ob das Ereignis null (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 die Operatoren definieren die Gleichheit von zwei List<T> als Vergleich aller enthaltenen Objekte mithilfe von Instanzen ihrer Equals Methoden.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 Destruktor ist ein Element, das die erforderlichen Aktionen zum zerstört einer Instanz einer Klasse implementiert.A destructor is a member that implements the actions required to destruct an instance of a class. Destruktoren können keine Parameter haben, sie können keine Zugriffsmodifizierer aufweisen und sie können nicht explizit aufgerufen werden.Destructors cannot have parameters, they cannot have accessibility modifiers, and they cannot be invoked explicitly. Der Destruktor für eine Instanz wird automatisch während der automatischen speicherbereinigung aufgerufen.The destructor for an instance is invoked automatically during garbage collection.

Der Garbage Collector kann entscheiden, wann Objekte sammeln und Destruktoren ausführen.The garbage collector is allowed wide latitude in deciding when to collect objects and run destructors. Insbesondere der Zeitpunkt der Destruktor aufrufen, ist nicht deterministisch und Destruktoren können in jedem Thread ausgeführt werden.Specifically, the timing of destructor invocations is not deterministic, and destructors may be executed on any thread. Für diesen und anderen Gründen sollten Klassen mit Destruktoren implementieren, nur, wenn keine andere Lösung möglich ist.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 ist, Point eine Struktur.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. Zum Beispiel die Ausgabe durch das folgende Codefragment davon abhängig, ob Point ist eine Klasse oder Struktur.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 ist eine Klasse, die Ausgabe ist 20 da a und b auf das gleiche Objekt verweisen.If Point is a class, the output is 20 because a and b reference the same object. Wenn Point ist eine Struktur, die Ausgabe ist 10 da die Zuweisung von a zu b erstellt eine Kopie des Werts, und diese Kopie ist nicht betroffen von der nachfolgenden Zuweisung zu a.x.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. Die tatsächlichen Arrayinstanzen werden dynamisch erstellt, zur Laufzeit mithilfe der new Operator.Actual array instances are created dynamically at run-time using the new operator. Die new Vorgang gibt die Länge der neuen Arrayinstanz, die dann für die Lebensdauer der Instanz behoben 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 folgende Beispiel weist ein eindimensionales, ein zweidimensionales und ein dreidimensionales Array.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.

Die new Operator erlaubt es, die Anfangswerte der Arrayelemente unter Verwendung einer Arrayinitialisierer, dies ist eine Liste von Ausdrücken, die zwischen den Trennzeichen { und }.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 abgeleitet wird { und }.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. Beispielsweise verwenden die folgenden Anweisungen dynamische Typumwandlungen zum Abrufen eines Objekts IControl und IDataBound schnittstellenimplementierungen.For example, the following statements use dynamic type casts to obtain an object's IControl and IDataBound interface implementations. Da der tatsächliche Typ des Objekts ist EditBox, 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, die Paint Methode aus der IControl Schnittstelle und die Bind Methode aus der IDataBound Schnittstelle implementiert werden, mithilfe von public Member.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 außerdem explizite Implementierungen eines Schnittstellenmembers, verwenden die Klasse oder Struktur kann vermeiden, dass die Mitglieder public.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. Z. B. die Implementierung der IControl.Paint bereitgestellt, die von der vorherigen EditBox Klasse kann nur aufgerufen werden, indem zunächst die EditBox Verweis auf die IControl Schnittstellentyp.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. Das folgende Beispiel deklariert und verwendet einen Enumerationstyp, der mit dem Namen Color mit drei Konstanten Werten Red, Green, und Blue.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 Enumerationstyp hat einen entsprechenden ganzzahligen Typ, der Namen der zugrunde liegender Typ des Enum-Typs.Each enum type has a corresponding integral type called the underlying type of the enum type. Ein Enumerationstyp, der nicht explizit einen zugrunde liegenden Typ deklariert, hat einen zugrunde liegenden Typ int.An enum type that does not explicitly declare an underlying type has an underlying type of int. Speicherformat und den Bereich der möglichen Werte eines Enumerationstyps werden durch die 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, die ein Enum-Typ übernehmen kann, ist nicht durch die Enumerationsmember beschränkt.The set of values that an enum type can take on is not limited by its enum members. Insbesondere ein Wert für den zugrunde liegenden Typ einer Enumeration in Enum-Typs umgewandelt werden kann und ein eindeutiger gültiger Wert dieses Enum-Typs ist.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.

Das folgende Beispiel deklariert einen Enum-Typ, der mit dem Namen Alignment mit einem zugrunde liegenden Typs sbyte.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 wird, zählen eine Enum-Element-Deklaration einen konstanten Ausdruck, 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 jede Enum-Element muss im Bereich von der zugrunde liegende Typ der Enumeration.The constant value for each enum member must be in the range of the underlying type of the enum. Wenn eine Enum-Memberdeklaration nicht explizit einen Wert angeben, erhält das Element den Wert 0 (null), (wenn es das erste Element in der Enumerationstyp ist) oder den Wert des textlich vorausgehenden Enum-Element plus 1.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.

Enum-Werte können in ganzzahlige Werte und umgekehrt mit Typumwandlungen 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 0 (null), die in den Enumerationstyp konvertiert.The default value of any enum type is the integral value zero converted to the enum type. In Fällen, in denen Variablen automatisch auf einen Standardwert initialisiert werden, ist dies der Wert, der Variablen von Enum-Typen.In cases where variables are automatically initialized to a default value, this is the value given to variables of enum types. In der Reihenfolge für den Standardwert eines Enumerationstyps leicht verfügbar ist, ist das Literal 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 gilt eine angegebenen Function für die Elemente der ein double[], zurückgeben eine double[] mit den Ergebnissen.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 das obige multiplikatorbeispiel geschrieben werden kann leichter ohne Verwendung einer Multiplier Klasse: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 Attributklassen leiten Sie von der System.Attribute Basisklasse, die von .NET Framework bereitgestellt.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 Sie den Namen eines Attributs endet Attribute, dieser Teil des Namens kann ausgelassen werden, wenn 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 fügt eine HelpAttribute auf die Widget -Klasse und eine weitere HelpAttribute auf die Display Methode in der Klasse.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).

Das folgende Beispiel zeigt, wie Informationen über Bildattribute für ein bestimmtes Programmentität zur Laufzeit abgerufen werden kann mithilfe von Reflektion.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.