Gewusst wie: Projizieren eines anonymen Typs

Aktualisiert: November 2007

Es gibt Fälle, in denen Sie eine Abfrage in einen neuen Typ projizieren möchten, obwohl Sie wissen, dass dieser Typ nur für kurze Zeit verwendet werden wird. Das Erstellen eines neuen Typs für die Verwendung in der Projektion bedeutet viel Zusatzarbeit. Effizienter wäre es in diesem Fall, eine Projektion in einen anonymen Typ vorzunehmen. Mit anonymen Typen können Sie eine Klasse definieren und dann ein Objekt dieser Klasse deklarieren und initialisieren, ohne der Klasse dazu einen Namen geben zu müssen.

Anonyme Typen stellen die C#-Implementierung des mathematischen Konzepts eines Tupels dar. Der mathematische Begriff "Tupel" bzw. "n-Tupel" (englisch "Tuple") leitet sich aus dem englischen Wortbestandteil "-(t)uple" für "-fach" (z. B. "quadruple" für "vierfach" und "quintuple" für "fünffach") ab. Er steht für eine endliche Abfolge von Objekten, die alle von einem bestimmten Typ sind. Mitunter wird dies als Liste von Name/Wert-Paaren bezeichnet. So könnte z. B. der Inhalt einer Adresse im XML-Dokument in Typical Purchase Order wie folgt ausgedrückt werden:

Name: Ellen Adams
Street: 123 Maple Street
City: Mill Valley
State: CA
Zip: 90952
Country: USA

Das Erstellen einer Instanz eines anonymen Typs lässt sich wie das Erstellen eines Tupels n-ter Ordnung vorstellen. Wenn Sie eine Abfrage schreiben, die ein Tupel in der select-Klausel erstellt, gibt die Abfrage eine IEnumerable des Tupels zurück.

Beispiel

In diesem Beispiel projiziert die select-Klausel einen anonymen Typ. Das Beispiel verwendet dann var, um das IEnumerable-Objekt zu erstellen. Innerhalb der foreach-Schleife wird die Iterationsvariable zu einer Instanz des im Abfrageausdruck erstellten anonymen Typs.

In diesem Beispiel wird das XML-Dokument in XML-Beispieldatei: Kunden ('Customers') und Aufträge ('Orders') (LINQ to XML) verwendet.

XElement custOrd = XElement.Load("CustomersOrders.xml");
var custList =
    from el in custOrd.Element("Customers").Elements("Customer")
    select new {
        CustomerID = (string)el.Attribute("CustomerID"),
        CompanyName = (string)el.Element("CompanyName"),
        ContactName = (string)el.Element("ContactName")
    };
foreach (var cust in custList)
    Console.WriteLine("{0}:{1}:{2}", cust.CustomerID, cust.CompanyName, cust.ContactName);
Dim custOrd As XElement = XElement.Load("CustomersOrders.xml")
Dim custList = _
    From el In custOrd.<Customers>.<Customer> _
    Select New With { _
        .CustomerID = el.@<CustomerID>, _
        .CompanyName = el.<CompanyName>.Value, _
        .ContactName = el.<ContactName>.Value _
    }
For Each cust In custList
    Console.WriteLine("{0}:{1}:{2}", cust.CustomerID, cust.CompanyName, cust.ContactName)
Next

Dieser Code erzeugt die folgende Ausgabe:

GREAL:Great Lakes Food Market:Howard Snyder
HUNGC:Hungry Coyote Import Store:Yoshi Latimer
LAZYK:Lazy K Kountry Store:John Steel
LETSS:Let's Stop N Shop:Jaime Yorres

Siehe auch

Konzepte

Projektionen und Transformationen (LINQ to XML)