Anonyme Typen

Anonyme Typen stellen eine praktische Möglichkeit dar, einen Satz schreibgeschützter Eigenschaften in einem Objekt zu kapseln, ohne zuerst explizit einen Typ definieren zu müssen. Der Typname wird vom Compiler generiert und ist auf Quellcodeebene nicht verfügbar. Der Typ der einzelnen Eigenschaften wird vom Compiler abgeleitet.

Sie erstellen anonyme Typen mithilfe des new Operators zusammen mit einem Objekt-Initializer. Informationen über Objektinitialisierer finden Sie unterObjekt- und Auflistungsinitialisierer.

Das folgende Beispiel veranschaulicht einen anonymen Typ, der mit den beiden Eigenschaften Amount und Message initialisiert wird.

var v = new { Amount = 108, Message = "Hello" };

// Rest the mouse pointer over v.Amount and v.Message in the following
// statement to verify that their inferred types are int and string.
Console.WriteLine(v.Amount + v.Message);

Anonyme Typen werden in der Regel in der select Klausel eines Abfrageausdrucks verwendet, um eine Teilmenge der Eigenschaften aus jedem Objekt in der Quellsequenz zurückzugeben. Weitere Informationen zu Abfragen finden Sie unter LINQ in C#.

Anonyme Typen enthalten mindestens eine schreibgeschützte Eigenschaft. Andere Arten von Klassenmembern wie Methoden oder Ereignisse sind ungültig. Der Ausdruck, der zum Initialisieren einer Eigenschaft verwendet wird, kann weder null noch eine anonyme Funktion oder ein Zeigertyp sein.

Das gängigste Szenario ist die Initialisierung eines anonymen Typs mit den Eigenschaften eines anderen Typs. Nehmen Sie im folgenden Beispiel an, dass eine Klasse mit dem Namen Product vorhanden ist. Die Product-Klasse enthält die Eigenschaften Color und Price sowie weitere Eigenschaften, die für Sie nicht relevant sind. Die Variable products ist eine Auflistung von Product-Objekten. Die Deklaration eines anonymen Typs beginnt mit dem Schlüsselwort new. Die Deklaration initialisiert einen neuen Typ, der nur zwei Eigenschaften von Product verwendet. Die Verwendung anonymer Typen führt dazu, dass in der Abfrage eine kleinere Menge von Daten zurückgegeben wird.

Wenn Sie keine Membernamen im anonymen Typ angeben, gibt der Compiler den anonymen Typmitgliedern denselben Namen wie die Eigenschaft, die verwendet wird, um sie zu initialisieren. Sie geben einen Namen für eine Eigenschaft an, die mit einem Ausdruck initialisiert wird, wie im vorherigen Beispiel gezeigt. Im folgenden Beispiel lauten die Namen der Eigenschaften des anonymen Typs Color und Price.

var productQuery =
    from prod in products
    select new { prod.Color, prod.Price };

foreach (var v in productQuery)
{
    Console.WriteLine("Color={0}, Price={1}", v.Color, v.Price);
}

Tipp

Sie können die .NET-Formatregel IDE0037 verwenden, um zu erzwingen, ob verzögerte oder explizite Membernamen bevorzugt werden.

Wenn Sie einen anonymen Typ zum Initialisieren einer Variablen verwenden, deklarieren Sie die Variable normalerweise mithilfe von var als implizit typisierte lokale Variable. Der Typname kann in der Variablendeklaration nicht angegeben werden, da nur der Compiler über Zugriff auf den zugrunde liegenden Namen des anonymen Typs verfügt. Weitere Informationen zu var finden Sie unter Implizit typisierte lokale Variablen.

Sie können ein Array anonym typisierter Elemente erstellen, indem Sie eine implizit typisierte lokale Variable und ein implizit typisiertes Array kombinieren, wie im folgenden Beispiel veranschaulicht.

var anonArray = new[] { new { name = "apple", diam = 4 }, new { name = "grape", diam = 1 }};

Anonyme Typen sind class Typen, die direkt von objecteinem Typ abgeleitet werden, und das kann nicht in einen beliebigen Typ gecastt werden, außer object. Der Compiler gibt für jeden anonymen Typ einen Namen an, Ihre Anwendung kann jedoch nicht darauf zugreifen. Aus der Perspektive der Common Language Runtime unterscheidet sich ein anonymer Typ nicht von anderen Verweistypen.

Wenn zwei oder mehr anonyme Objektinitialisierer in einer Assembly eine Sequenz von Eigenschaften angeben, die die gleiche Reihenfolge und die gleichen Namen und Typen aufweisen, behandelt der Compiler die Objekte als Instanzen desselben Typs. Sie erhalten die gleichen vom Compiler generierten Typinformationen.

Anonyme Typen unterstützen nicht destruktive Mutationen in Form von Ausdrücken. Dadurch können Sie eine neue Instanz eines anonymen Typs erstellen, in dem mindestens eine Eigenschaft neue Werte aufweist:

var apple = new { Item = "apples", Price = 1.35 };
var onSale = apple with { Price = 0.79 };
Console.WriteLine(apple);
Console.WriteLine(onSale);

Sie können ein Feld, eine Eigenschaft, ein Ereignis oder den Rückgabetyp einer Methode nicht mit einem anonymen Typ deklarieren. Auch können Sie einen formalen Parameter einer Methode, einer Eigenschaft, eines Konstruktors oder eines Indexers nicht als anonymen Typ deklarieren. Um einen anonymen Typ oder eine Auflistung, die anonyme Typen enthält, als Argument an eine Methode zu übergeben, können Sie den Parameter als Typ objectdeklarieren. Die Verwendung object für anonyme Typen schlägt jedoch den Zweck einer starken Eingabe ab. Wenn Sie Abfrageergebnisse speichern oder außerhalb der Methodengrenze übergeben müssen, könnten Sie statt eines anonymen Typs eine Struktur oder Klasse mit einem gewöhnlichen Namen verwenden.

Da die Methoden Equals und GetHashCode von anonymen Typen anhand der Methoden Equals und GetHashCode der Eigenschaften definiert werden, sind zwei Instanzen eines anonymen Typs nur gleich, wenn alle Eigenschaften gleich sind.

Anonyme Typen überschreiben die Methode, verkettet den ToString Namen und ToString die Ausgabe jeder Eigenschaft, die durch curly Klammern umgeben ist.

var v = new { Title = "Hello", Age = 24 };

Console.WriteLine(v.ToString()); // "{ Title = Hello, Age = 24 }"