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.
Eine Klassen- oder Strukturdefinition ist wie eine Blaupause, die angibt, was der Typ tun kann. Ein Objekt ist ein Speicherblock, den das Programm gemäß dem Blueprint zuordnet und konfiguriert. Ein Programm kann viele Objekte derselben Klasse erstellen. Sie können auch Objekteinstanzen aufrufen. Sie können sie in einer benannten Variablen oder in einer Matrix oder Sammlung speichern. Clientcode verwendet diese Variablen, um die Methoden aufzurufen und auf die öffentlichen Eigenschaften des Objekts zuzugreifen. In einer objektorientierten Sprache wie C# besteht ein typisches Programm aus mehreren Objekten, die dynamisch interagieren.
Hinweis
Statische Typen verhalten sich anders als in diesem Artikel beschrieben. Weitere Informationen finden Sie unter "Static Classes" und "Static Class Members".
Strukturinstanzen im Vergleich zu Klasseninstanzen
Da Klassen Referenztypen sind, enthält eine Variable eines Klassenobjekts einen Verweis auf die Adresse des Objekts im verwalteten Heap. Wenn Sie der ersten Variablen eine zweite Variable desselben Typs zuweisen, verweisen beide Variablen auf das Objekt an dieser Adresse. In diesem Artikel wird dieser Punkt später ausführlicher erläutert.
Sie erstellen Instanzen von Klassen mithilfe des new Operators. Im folgenden Beispiel Person handelt es sich um den Typ und person1person2 sind Instanzen oder Objekte dieses Typs.
using System;
public class Person(string name, int age)
{
public string Name { get; set; } = name;
public int Age { get; set; } = age;
// Other properties, methods, events...
}
class Program
{
static void Main()
{
Person person1 = new("Leopold", 6);
Console.WriteLine($"person1 Name = {person1.Name} Age = {person1.Age}");
// Declare new person, assign person1 to it.
Person person2 = person1;
// Change the name of person2, and person1 also changes.
person2.Name = "Molly";
person2.Age = 16;
Console.WriteLine($"person2 Name = {person2.Name} Age = {person2.Age}");
Console.WriteLine($"person1 Name = {person1.Name} Age = {person1.Age}");
/*
Output:
person1 Name = Leopold Age = 6
person2 Name = Molly Age = 16
person1 Name = Molly Age = 16
*/
}
}
Da Strukturen Werttypen sind, enthält eine Variable eines Strukturobjekts eine Kopie des gesamten Objekts. Sie können auch Instanzen von Strukturen mithilfe des new Operators erstellen, aber sie müssen nicht verwendet werden, wie im folgenden Beispiel gezeigt:
using System;
namespace Example
{
public struct Person
{
public string Name;
public int Age;
public Person(string name, int age)
{
Name = name;
Age = age;
}
}
public class Application
{
static void Main()
{
// Create struct instance and initialize by using "new".
// Memory is allocated on thread stack.
Person p1 = new("Alex", 9);
Console.WriteLine($"p1 Name = {p1.Name} Age = {p1.Age}");
// Create new struct object. Note that struct can be initialized
// without using "new".
Person p2 = p1;
// Assign values to p2 members.
p2.Name = "Spencer";
p2.Age = 7;
Console.WriteLine($"p2 Name = {p2.Name} Age = {p2.Age}");
// p1 values remain unchanged because p2 is copy.
Console.WriteLine($"p1 Name = {p1.Name} Age = {p1.Age}");
}
}
/*
Output:
p1 Name = Alex Age = 9
p2 Name = Spencer Age = 7
p1 Name = Alex Age = 9
*/
}
Der Stack eines Threads reserviert Speicher sowohl für p1 als auch für p2. Das Programm gibt diesen Speicher zusammen mit dem Typ oder der Methode zurück, in dem Sie ihn deklarieren. Diese Speicherverwaltung ist ein Grund dafür, warum Strukturen für die Zuordnung kopiert werden. Im Gegensatz dazu gibt die Common Language Runtime den Speicher, den sie für eine Klasseninstanz zuweist, automatisch frei (führt eine Garbage Collection durch), wenn alle Referenzen auf das Objekt außerhalb ihres Gültigkeitsbereichs fallen. Sie können ein Klassenobjekt wie in C++ nicht deterministisch zerstören. Weitere Informationen zur Garbage Collection in .NET finden Sie unter Garbage Collection.
Hinweis
Die Common Language Runtime optimiert stark die Belegung und Freigabe von Arbeitsspeicher auf dem verwalteten Heap. In den meisten Fällen besteht kein signifikanter Unterschied bei den Leistungskosten beim Zuweisen einer Klasseninstanz auf dem Heap im Vergleich zur Zuordnung einer Strukturinstanz im Stapel.
Objektidentität im Vergleich zur Wertgleichheit
Wenn Sie zwei Objekte für die Gleichheit vergleichen, entscheiden Sie zuerst, ob die beiden Variablen dasselbe Objekt im Arbeitsspeicher darstellen oder ob die Werte eines oder mehrerer felder gleichwertig sind. Wenn Sie Werte vergleichen möchten, überlegen Sie, ob es sich bei den Objekten um Instanzen von Werttypen (Strukturen) oder Referenztypen (Klassen, Stellvertretungen, Arrays) handelt.
Verwenden Sie die statische Object.ReferenceEquals Methode, um zu bestimmen, ob zwei Klasseninstanzen auf denselben Speicherort im Speicher verweisen (was bedeutet, dass sie dieselbe Identität haben). (System.Object ist die implizite Basisklasse für alle Werttypen und Verweistypen, einschließlich benutzerdefinierter Strukturen und Klassen.)
Standardmäßig bestimmt die ValueType.Equals Methode, ob die Instanzfelder in zwei Strukturinstanzen dieselben Werte aufweisen. Da alle Strukturen implizit von System.ValueType erben, rufen Sie die Methode direkt auf Ihrem Objekt auf, wie im folgenden Beispiel gezeigt:
// Person is defined in the previous example. //public struct Person(string name, int age) //{ // public string Name { get; set; } = name; // public int Age { get; set; } = age; //} Person p1 = new("Wallace", 75); Person p2 = new("", 42); p2.Name = "Wallace"; p2.Age = 75; if (p2.Equals(p1)) Console.WriteLine("p2 and p1 have the same values."); // Output: p2 and p1 have the same values.Die standardmäßige System.ValueType-Implementierung von
Equalsverwendet in einigen Fällen Boxing und Reflexion. Informationen zum Bereitstellen eines effizienten Gleichheitsalgorithmus, der für Ihren Typ spezifisch ist, finden Sie unter Implementieren der Gleichheit selbst, wenn ein Typ kein Datensatz sein kann. Datensätze sind Referenztypen, die Wertsemantik für Gleichheit verwenden.Um zu ermitteln, ob die Werte der Felder in zwei Klasseninstanzen gleich sind, können Sie die Methode oder den Equals verwenden. Verwenden Sie sie jedoch nur, wenn die Klasse die Werte überschrieben oder überladen hat, um eine benutzerdefinierte Definition von „Gleichheit“ für Objekte dieses Typs bereitzustellen. Die Klasse kann auch die IEquatable<T> Schnittstelle oder die IEqualityComparer<T> Schnittstelle implementieren. Beide Schnittstellen stellen Methoden bereit, die zum Testen der Wertgleichstellung verwendet werden können. Achten Sie beim Entwerfen eigener Klassen, die
Equalsüberschreiben, darauf, die in Implementieren Sie Gleichheit selbst, wenn ein Typ kein Record sein kann und Object.Equals(Object) beschriebenen Richtlinien zu befolgen.
Verwandte Abschnitte
Weitere Informationen findest du unter: