Freigeben über


Anonyme Typen (C#-Programmierhandbuch)

Anonyme Typen bieten eine bequeme Möglichkeit, einen Satz schreibgeschützter Eigenschaften in ein einzelnes Objekt zu kapseln, ohne zuerst einen benannten Typ zu definieren. Der Compiler generiert zur Kompilierungszeit einen Typnamen, auf den Sie im Quellcode nicht zugreifen können. Der Compiler leitet den Typ jeder Eigenschaft ab.

Erstellen Sie anonyme Typen mithilfe des new Operators zusammen mit einem Objektinitialisierer. Das folgende Beispiel zeigt einen anonymen Typ, der mit zwei Eigenschaften initialisiert wird, Name und Age:

var person = new { Name = "Alice", Age = 30 };
Console.WriteLine($"{person.Name} is {person.Age} years old.");
// Output:
// Alice is 30 years old.

Abgeleitete Eigenschaftsnamen

Sie können Eigenschaftsnamen explizit mithilfe der Name = value Syntax angeben. Wenn Sie einen anonymen Typ mit einem Variablen- oder Memberzugriffsausdruck initialisieren, leitet der Compiler den Eigenschaftennamen aus diesem Ausdruck ab:

string productName = "Laptop";
decimal price = 999.99m;
var product = new { productName, price };
Console.WriteLine($"{product.productName}: {product.price:C}");
// Output:
// Laptop: $999.99

Im vorherigen Beispiel leitet der Compiler productName und price als Eigenschaftsnamen von den in der Initialisierung verwendeten Variablennamen ab.

Anonyme Typen mit Var deklarieren

Da der Compiler den Typnamen generiert und Sie im Quellcode nicht auf ihn zugreifen können, müssen Sie var verwenden, um die lokale Variable zu deklarieren. Sie können den Typnamen nicht explizit angeben:

// You must use var — you can't write a named type here.
var person = new { Name = "Alice", Age = 30 };

Verwenden von anonymen Typen in LINQ-Abfragen

Anonyme Typen werden am häufigsten in der select Klausel eines Abfrageausdrucks angezeigt, in der sie eine Teilmenge von Eigenschaften aus jedem Quellelement projizieren:

var words = new[] { "apple", "blueberry", "cherry" };

var results = words.Select(w => new { Word = w, Length = w.Length });

foreach (var item in results)
{
    Console.WriteLine($"{item.Word} has {item.Length} letters.");
}
// Output:
// apple has 5 letters.
// blueberry has 9 letters.
// cherry has 6 letters.

Gleichheit

Zwei anonyme Typinstanzen, die dieselben Eigenschaftsnamen und -typen in derselben Reihenfolge aufweisen, verwenden denselben compilergenerierten Typ. Der Compiler überschreibt Equals und GetHashCode sodass die Gleichheit Eigenschaftswerte anstelle von Referenzidentitäten vergleicht:

var a = new { Name = "Alice", Age = 30 };
var b = new { Name = "Alice", Age = 30 };
var c = new { Name = "Bob", Age = 25 };

Console.WriteLine(a.Equals(b));  // True
Console.WriteLine(a.Equals(c));  // False

Geschachtelte anonyme Typen

Anonyme Typen können andere anonyme Typen als Eigenschaftswerte enthalten:

var order = new
{
    OrderId = 1,
    Customer = new { Name = "Alice", City = "Seattle" },
    Total = 150.00m
};
Console.WriteLine($"Order {order.OrderId} for {order.Customer.Name} in {order.Customer.City}");
// Output:
// Order 1 for Alice in Seattle

Merkmale

Anonyme Typen weisen die folgenden Merkmale auf:

  • Der Compiler erzeugt sie als internal sealed class-Typen, die von Object abgeleitet sind.
  • Alle Eigenschaften sind public und schreibgeschützt.
  • Anonyme Typen unterstützen with Ausdrücke für nicht destruktive Mutationen.
  • Der Compiler generiert wertbasierte Equals, GetHashCodeund ToString Überschreibungen.
  • Anonyme Typen unterstützen Ausdrucksbäume, während Tupel dies nicht tun.

Einschränkungen

Anonyme Typen haben mehrere Einschränkungen:

  • Sie können sie nicht als Methodenrückgabetypen, Methodenparameter oder Feldtypen verwenden, da Sie den Typ nicht benennen können.
  • Sie sind auf die Methode eingegrenzt, in der Sie sie deklarieren.
  • Sie können keine Methoden, Ereignisse oder benutzerdefinierte Operatoren hinzufügen.
  • Eigenschaften sind immer schreibgeschützt; Anonyme Typen unterstützen keine veränderbaren Eigenschaften.

Wann stattdessen Tupel verwendet werden sollen

Für den Großteil neuen Codes sollten Sie Tupel anstelle anonymer Typen verwenden. Als Werttypen bieten Tupel eine bessere Programmierleistung. Sie bieten auch Unterstützung für die Dekonstruktion und flexiblere Syntax. Anonyme Typen bleiben die bessere Wahl, wenn Sie Unterstützung für Ausdrucksbäume oder Referenztypsemantik benötigen. Einen detaillierten Vergleich finden Sie in Auswahl zwischen anonymen und Tupeltypen.

Siehe auch