Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Tipp
Neu bei der Entwicklung von Software? Beginnen Sie zuerst mit den Lernprogrammen " Erste Schritte ". Sie werden auf Klassen stoßen, sobald Sie Objekte mit Verhalten und Zustand modellieren müssen.
Haben Sie Erfahrung in einer anderen Sprache? C#-Klassen ähneln Klassen in Java oder C++. Überspringen Sie die Abschnitte für Objektinitialisierer und Sammlungsinitialisierer für C#-spezifische Muster, und siehe Datensätze für eine datenorientierte Alternative.
Eine Klasse ist ein Verweistyp, der einen Blueprint für Objekte definiert. Wenn Sie eine Variable eines Klassentyps erstellen, enthält die Variable einen Verweis auf ein Objekt im verwalteten Heap. Die Variable enthält die Objektdaten nicht selbst. Durch das Zuweisen einer Klassenvariable zu einer anderen Variablen wird der Verweis kopiert, sodass beide Variablen auf dasselbe Objekt verweisen. Klassen sind die am häufigsten verwendete Methode zum Definieren von benutzerdefinierten Typen in C#. Verwenden Sie sie, wenn Sie komplexes Verhalten, Vererbung oder gemeinsame Identität zwischen Verweisen benötigen.
Deklarieren einer Klasse
Definieren Sie eine Klasse mit dem class Schlüsselwort gefolgt vom Typnamen. Ein optionaler Zugriffsmodifizierer steuert die Sichtbarkeit. Der Standardwert ist internal:
public class Customer
{
public string Name { get; set; }
public Customer(string name) => Name = name;
}
Der Klassenkörper enthält Felder, Eigenschaften, Methoden und Ereignisse, die zusammen als Klassenmitglieder bezeichnet werden. Der Name muss ein gültiger C# -Bezeichnername sein.
Objekte erstellen
Eine Klasse definiert einen Typ, ist aber kein Objekt selbst. Sie erstellen ein Objekt (eine Instanz der Klasse) mit dem new Schlüsselwort:
var customer = new Customer("Allison");
Console.WriteLine(customer.Name); // Allison
Die Variable customer enthält einen Verweis auf das Objekt, nicht das Objekt selbst. Sie können demselben Objekt mehrere Variablen zuweisen. Änderungen durch einen Verweis sind durch die andere sichtbar:
var c1 = new Customer("Grace");
var c2 = c1; // both variables reference the same object
c2.Name = "Hopper";
Console.WriteLine(c1.Name); // Hopper — c1 sees the change made through c2
Dieses Referenzfreigabeverhalten ist eine Unterscheidung zwischen Klassen und Strukturen, bei denen die Zuordnung die Daten kopiert. Wichtiger ist, dass Klassen die Vererbung unterstützen. Sie können Hierarchien erstellen, in denen abgeleitete Typen das Verhalten einer Basisklasse wiederverwenden und spezialisieren. Strukturen können nicht an Vererbungshierarchien teilnehmen. Weitere Informationen zur Unterscheidung finden Sie unter Werttypen und Referenztypen.
Konstruktoren und Initialisierung
Wenn Sie eine Instanz erstellen, sollen die zugehörigen Felder und Eigenschaften für nützliche Werte initialisiert werden. C# bietet verschiedene Ansätze: Feldinitialisierer, Konstruktorparameter, primäre Konstruktoren und erforderliche Eigenschaften.
Feldinitialisierer legen einen Standardwert direkt in der Felddeklaration fest:
public class Container
{
private int _capacity = 10;
}
Feldinitialisierer definieren interne Standardwerte. Sie geben Anrufern keine Möglichkeit, den Anfangswert auszuwählen. Verwenden Sie eine der folgenden Techniken, damit Verbraucher der Klasse einen Wert bereitstellen können.
Konstruktorparameter erfordern, dass die Aufrufer Werte bereitstellen.
public class Container
{
private int _capacity;
public Container(int capacity) => _capacity = capacity;
}
Primäre Konstruktoren (C# 12+) fügen der Klassendeklaration Parameter direkt hinzu. Diese Parameter sind im gesamten Klassenkörper verfügbar.
public class Container(int capacity)
{
private int _capacity = capacity;
}
Primäre Konstruktoren und Feldinitialisierer können zusammenarbeiten: Der Feldinitialisierer _capacity = capacity verwendet den Primärkonstruktorparameter als Wert. Mit diesem Muster können Sie Konstruktorargumente in Feldern mit einer einzelnen, präzisen Deklaration erfassen.
Erforderliche Eigenschaften erzwingen, dass Aufrufer bestimmte Eigenschaften über einen Objektinitialisierer festlegen:
public class Person
{
public required string FirstName { get; set; }
public required string LastName { get; set; }
}
// var missing = new Person(); // Error: required properties not set
var person = new Person { FirstName = "Grace", LastName = "Hopper" };
Console.WriteLine($"{person.FirstName} {person.LastName}"); // Grace Hopper
Einen tieferen Einblick in Konstruktormuster, einschließlich Parameterüberprüfung und Konstruktorketten, finden Sie unter "Konstruktoren".
Statische Klassen
Eine static Klasse kann nicht instanziiert werden und enthält nur statische Member. Verwenden Sie statische Klassen, um Hilfsmethoden zu organisieren, die nicht für Instanzdaten verwendet werden:
static class MathHelpers
{
public static double CircleCircumference(double radius) =>
2 * Math.PI * radius;
}
double circumference = MathHelpers.CircleCircumference(5.0);
Console.WriteLine($"Circumference: {circumference:F2}"); // Circumference: 31.42
Die .NET-Klassenbibliothek enthält viele statische Klassen, wie z. B. Math und Console. Eine statische Klasse ist implizit versiegelt. Sie können sie nicht ableiten oder instanziieren.
Objektinitialisierer
Mit Objektinitialisierern können Sie Eigenschaften festlegen, wenn Sie ein Objekt erstellen, ohne einen Konstruktor für jede Kombination von Werten zu schreiben:
class ConnectionOptions
{
public string Host { get; init; } = "localhost";
public int Port { get; init; } = 80;
public bool UseSsl { get; init; }
}
var options = new ConnectionOptions
{
Host = "db.example.com",
Port = 5432,
UseSsl = true
};
Console.WriteLine($"{options.Host}:{options.Port} (SSL: {options.UseSsl})");
// db.example.com:5432 (SSL: True)
Objektinitialisierer funktionieren mit jeder zugänglichen Eigenschaft, die über einen set- oder init-Accessor verfügt. Sie werden auf natürliche Weise mit required-Eigenschaften und mit Konstruktoren kombiniert, die einige Parameter akzeptieren, während sie dem Aufrufer die Festlegung anderer überlassen.
Auflistungsinitialisierer
Eine Auflistung ist ein Typ, der eine Gruppe verwandter Werte enthält– Listen, Sätze, Wörterbücher, Arrays und Spans sind alle gängigen Beispiele. Die .NET-Klassenbibliothek bietet allgemeine Sammlungstypen wie List<T>, Dictionary<TKey,TValue> und HashSet<T> neben Arrays und Span<T>.
Mit Auflistungsausdrücken (C# 12+) können Sie eine Auflistung inline auffüllen, wenn Sie sie mit der Klammernsyntax erstellen:
List<string> languages = ["C#", "F#", "Visual Basic"];
// The spread operator (..) composes collections from existing sequences:
List<string> moreLangs = [.. languages, "Python", "TypeScript"];
Console.WriteLine(string.Join(", ", moreLangs));
// C#, F#, Visual Basic, Python, TypeScript
Sammlungsausdrücke funktionieren mit Arrays, List<T>, Span<T> und jedem Typ, der die Sammlungsinitialisierung unterstützt. Der Spread-Operator (..) fügt alle Elemente aus dessen Operanden in die neue Auflistung ein. Der Operand muss keine vollständige Auflistung sein – es kann sich um einen beliebigen Ausdruck handeln, der eine Sequenz erzeugt, z. B. einen Unterbereich, eine LINQ-Abfrage oder eine gefilterte Teilmenge. Weitere Informationen finden Sie unter Auflistungsausdrücke (C#-Referenz).
Vererbung
Klassen unterstützen die Vererbung. Sie können eine neue Klasse definieren, die das Verhalten einer vorhandenen Klasse wiederverwendet, erweitert oder ändert. Die klasse, von der Sie erben, ist die Basisklasse, und die neue Klasse ist die abgeleitete Klasse:
var manager = new Manager("Satya", "Engineering");
Console.WriteLine($"{manager.Name} manages {manager.Department}");
// Satya manages Engineering
Eine Klasse kann von einer Basisklasse erben und mehrere Schnittstellen implementieren. Abgeleitete Klassen erben alle Member der Basisklasse mit Ausnahme von Konstruktoren. Weitere Informationen finden Sie unter Vererbung und Schnittstellen.
Wann man Klassen verwenden sollte
Verwenden Sie eine Klasse in folgenden Fällen:
- Der Typ weist ein komplexes Verhalten auf oder verwaltet den veränderbaren Zustand.
- Sie benötigen die Vererbung, um eine Basisklasse mit abgeleiteten Spezialisierungen zu erstellen oder einen abgeleiteten Typ zu erstellen, der eine vorhandene Klasse erweitert.
- Instanzen stellen eine gemeinsame Identität dar, nicht nur ein Datenbündel (zwei Verweise auf dasselbe Objekt sollten synchronisiert bleiben).
- Der Typ ist groß oder langlebig und profitiert von heap-Zuordnung und Referenzsemantik.