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.
Visual Basic unterstützt anonyme Typen, mit denen Sie Objekte erstellen können, ohne eine Klassendefinition für den Datentyp zu schreiben. Stattdessen generiert der Compiler eine Klasse für Sie. Die Klasse hat keinen verwendbaren Namen, erbt direkt von Object, und enthält die Eigenschaften, die Sie beim Deklarieren des Objekts angeben. Da der Name des Datentyps nicht angegeben ist, wird er als anonymer Typ bezeichnet.
Im folgenden Beispiel wird die Variable product
als Instanz eines anonymen Typs deklariert und erstellt, die zwei Eigenschaften aufweist, Name
und Price
.
' Variable product is an instance of a simple anonymous type.
Dim product = New With {Key .Name = "paperclips", .Price = 1.29}
Ein Abfrageausdruck verwendet anonyme Typen, um Datenspalten zu kombinieren, die von einer Abfrage ausgewählt wurden. Sie können den Typ des Ergebnisses im Voraus nicht definieren, da Sie die Spalten, die eine bestimmte Abfrage auswählen kann, nicht vorhersagen können. Mit anonymen Typen können Sie eine Abfrage schreiben, die eine beliebige Anzahl von Spalten in beliebiger Reihenfolge auswählt. Der Compiler erstellt einen Datentyp, der den angegebenen Eigenschaften und der angegebenen Reihenfolge entspricht.
In den folgenden Beispielen products
handelt es sich um eine Liste von Produktobjekten, die jeweils über viele Eigenschaften verfügen. Variable namePriceQuery
enthält die Definition einer Abfrage, die, wenn sie ausgeführt wird, eine Auflistung von Instanzen eines anonymen Typs zurückgibt, die zwei Eigenschaften aufweisen, Name
und Price
.
Dim namePriceQuery = From prod In products
Select prod.Name, prod.Price
Variable nameQuantityQuery
enthält die Definition einer Abfrage, die, wenn sie ausgeführt wird, eine Auflistung von Instanzen eines anonymen Typs zurückgibt, die zwei Eigenschaften aufweisen, Name
und OnHand
.
Dim nameQuantityQuery = From prod In products
Select prod.Name, prod.OnHand
Weitere Informationen zum vom Compiler für einen anonymen Typ erstellten Code finden Sie unter "Definition des anonymen Typs".
Vorsicht
Der Name des anonymen Typs wird vom Compiler generiert und kann von Kompilierung zu Kompilierung variieren. Ihr Code sollte nicht den Namen eines anonymen Typs verwenden oder sich darauf verlassen, da sich der Name ändern kann, wenn ein Projekt neu kompiliert wird.
Deklarieren eines anonymen Typs
Die Deklaration einer Instanz eines anonymen Typs verwendet eine Initialisierungsliste, um die Eigenschaften des Typs anzugeben. Sie können nur Eigenschaften angeben, wenn Sie einen anonymen Typ deklarieren, nicht andere Klassenelemente wie Methoden oder Ereignisse. Im folgenden Beispiel product1
handelt es sich um eine Instanz eines anonymen Typs mit zwei Eigenschaften: Name
und Price
.
' Variable product1 is an instance of a simple anonymous type.
Dim product1 = New With {.Name = "paperclips", .Price = 1.29}
' -or-
' product2 is an instance of an anonymous type with key properties.
Dim product2 = New With {Key .Name = "paperclips", Key .Price = 1.29}
Wenn Sie Eigenschaften als Schlüsseleigenschaften festlegen, können Sie sie verwenden, um zwei anonyme Typinstanzen für Gleichheit zu vergleichen. Die Werte der Schlüsseleigenschaften können jedoch nicht geändert werden. Weitere Informationen finden Sie im Abschnitt "Wichtige Eigenschaften" weiter unten in diesem Thema.
Beachten Sie, dass das Deklarieren einer Instanz eines anonymen Typs wie das Deklarieren einer Instanz eines benannten Typs mithilfe eines Objektinitialisierungsprogramms ist:
' Variable product3 is an instance of a class named Product.
Dim product3 = New Product With {.Name = "paperclips", .Price = 1.29}
Weitere Informationen zu anderen Methoden zum Angeben von Eigenschaften für anonyme Typen finden Sie unter How to: Infer Property Names and Types in Anonymous Type Declarations.
Schlüsseleigenschaften
Wichtige Eigenschaften unterscheiden sich auf verschiedene grundlegende Weise von Nicht-Schlüsseleigenschaften:
Es werden nur die Werte der Schlüsseleigenschaften verglichen, um festzustellen, ob zwei Instanzen gleich sind.
Die Werte der Schlüsseleigenschaften sind nur-lesbar und können nicht geändert werden.
Nur wichtige Eigenschaftswerte sind im vom Compiler generierten Hashcodealgorithmus für einen anonymen Typ enthalten.
Gleichheit
Instanzen anonymer Typen können nur gleich sein, wenn sie Instanzen desselben anonymen Typs sind. Der Compiler behandelt zwei Instanzen als Instanzen desselben Typs, wenn sie die folgenden Bedingungen erfüllen:
Sie werden in derselben Assembly deklariert.
Ihre Eigenschaften haben dieselben Namen, dieselben abgeleiteten Typen und werden in derselben Reihenfolge deklariert. Bei Namensvergleichen wird die Groß-/Kleinschreibung nicht beachtet.
Die gleichen Eigenschaften werden jeweils als Schlüsseleigenschaften markiert.
Mindestens eine Eigenschaft in jeder Deklaration ist eine Schlüsseleigenschaft.
Eine Instanz eines anonymen Typs, der keine Schlüsseleigenschaften aufweist, ist nur für sich selbst gleich.
' prod1 and prod2 have no key values.
Dim prod1 = New With {.Name = "paperclips", .Price = 1.29}
Dim prod2 = New With {.Name = "paperclips", .Price = 1.29}
' The following line displays False, because prod1 and prod2 have no
' key properties.
Console.WriteLine(prod1.Equals(prod2))
' The following statement displays True because prod1 is equal to itself.
Console.WriteLine(prod1.Equals(prod1))
Zwei Instanzen desselben anonymen Typs sind gleich, wenn die Werte ihrer Schlüsseleigenschaften gleich sind. Die folgenden Beispiele veranschaulichen, wie die Gleichheit getestet wird.
Dim prod3 = New With {Key .Name = "paperclips", Key .Price = 1.29}
Dim prod4 = New With {Key .Name = "paperclips", Key .Price = 1.29}
' The following line displays True, because prod3 and prod4 are
' instances of the same anonymous type, and the values of their
' key properties are equal.
Console.WriteLine(prod3.Equals(prod4))
Dim prod5 = New With {Key .Name = "paperclips", Key .Price = 1.29}
Dim prod6 = New With {Key .Name = "paperclips", Key .Price = 1.29,
.OnHand = 423}
' The following line displays False, because prod5 and prod6 do not
' have the same properties.
Console.WriteLine(prod5.Equals(prod6))
Dim prod7 = New With {Key .Name = "paperclips", Key .Price = 1.29,
.OnHand = 24}
Dim prod8 = New With {Key .Name = "paperclips", Key .Price = 1.29,
.OnHand = 423}
' The following line displays True, because prod7 and prod8 are
' instances of the same anonymous type, and the values of their
' key properties are equal. The equality check does not compare the
' values of the non-key field.
Console.WriteLine(prod7.Equals(prod8))
Read-Only Werte
Die Werte der Schlüsseleigenschaften können nicht geändert werden. In prod8
im vorherigen Beispiel sind die Felder Name
und Price
read-only
, aber OnHand
kann geändert werden.
' The following statement will not compile, because Name is a key
' property and its value cannot be changed.
' prod8.Name = "clamps"
' OnHand is not a Key property. Its value can be changed.
prod8.OnHand = 22
Anonyme Typen von Abfrageausdrücken
Abfrageausdrücke erfordern nicht immer die Erstellung anonymer Typen. Wenn möglich, verwenden sie einen vorhandenen Typ, um die Spaltendaten zu enthalten. Dies tritt auf, wenn die Abfrage entweder ganze Datensätze aus der Datenquelle oder nur ein Feld aus jedem Datensatz zurückgibt. In den folgenden Codebeispielen customers
handelt es sich um eine Auflistung von Objekten einer Customer
Klasse. Die Klasse verfügt über viele Eigenschaften, und Sie können eine oder mehrere davon in das Abfrageergebnis in beliebiger Reihenfolge einschließen. In den ersten beiden Beispielen sind keine anonymen Typen erforderlich, da die Abfragen Elemente benannter Typen auswählen:
custs1
enthält eine Auflistung von Zeichenfolgen, da es sich umcust.Name
eine Zeichenfolge handelt.Dim custs1 = From cust In customers Select cust.Name
custs2
enthält eine Auflistung vonCustomer
Objekten, da jedes Elementcustomers
einCustomer
Objekt ist und das gesamte Element von der Abfrage ausgewählt wird.Dim custs2 = From cust In customers Select cust
Entsprechende benannte Typen sind jedoch nicht immer verfügbar. Möglicherweise möchten Sie Kundennamen und -adressen für einen Zweck, Kunden-ID-Nummern und Standorte für einen anderen sowie Kundennamen, Adressen und Bestellhistorien für ein Drittes auswählen. Anonyme Typen ermöglichen es Ihnen, eine beliebige Kombination von Eigenschaften in beliebiger Reihenfolge auszuwählen, ohne zuerst einen neuen benannten Typ zu deklarieren, um das Ergebnis zu enthalten. Stattdessen erstellt der Compiler für jede Zusammenstellung von Eigenschaften einen anonymen Typ. Die folgende Abfrage wählt nur den Namen und die ID-Nummer des Kunden aus jedem Customer
Objekt aus customers
. Daher erstellt der Compiler einen anonymen Typ, der nur diese beiden Eigenschaften enthält.
Dim custs3 = From cust In customers
Select cust.Name, cust.ID
Sowohl die Namen als auch die Datentypen der Eigenschaften im anonymen Typ werden aus den Argumenten von Select
, cust.Name
und cust.ID
übernommen. Die Eigenschaften in einem anonymen Typ, der von einer Abfrage erstellt wird, sind immer wichtige Eigenschaften. Wenn custs3
in der folgenden For Each
Schleife ausgeführt wird, ist das Ergebnis eine Sammlung von Instanzen eines anonymen Typs mit zwei Schlüsseleigenschaften Name
und ID
.
For Each selectedCust In custs3
Console.WriteLine(selectedCust.ID & ": " & selectedCust.Name)
Next
Die Elemente in der Auflistung, die durch custs3
dargestellt werden, sind stark typisiert. Sie können IntelliSense verwenden, um durch die verfügbaren Eigenschaften zu navigieren und deren Typen zu überprüfen.
Weitere Informationen finden Sie unter Einführung in LINQ in Visual Basic.
Entscheiden, ob anonyme Typen verwendet werden sollen
Bevor Sie ein Objekt als Instanz einer anonymen Klasse erstellen, überlegen Sie, ob dies die beste Option ist. Wenn Sie z. B. ein temporäres Objekt erstellen möchten, das verwandte Daten enthält, und Sie keine Notwendigkeit für andere Felder und Methoden haben, die eine vollständige Klasse enthalten kann, ist ein anonymer Typ eine gute Lösung. Anonyme Typen sind auch praktisch, wenn Sie für jede Deklaration eine andere Auswahl von Eigenschaften wünschen oder wenn Sie die Reihenfolge der Eigenschaften ändern möchten. Wenn Ihr Projekt jedoch mehrere Objekte mit den gleichen Eigenschaften enthält, können Sie sie einfacher deklarieren, indem Sie einen benannten Typ mit einem Klassenkonstruktor verwenden. Beispielsweise ist es mit einem geeigneten Konstruktor einfacher, mehrere Instanzen einer Product
Klasse zu deklarieren, als mehrere Instanzen eines anonymen Typs zu deklarieren.
' Declaring instances of a named type.
Dim firstProd1 As New Product("paperclips", 1.29)
Dim secondProd1 As New Product("desklamp", 28.99)
Dim thirdProd1 As New Product("stapler", 5.09)
' Declaring instances of an anonymous type.
Dim firstProd2 = New With {Key .Name = "paperclips", Key .Price = 1.29}
Dim secondProd2 = New With {Key .Name = "desklamp", Key .Price = 28.99}
Dim thirdProd2 = New With {Key .Name = "stapler", Key .Price = 5.09}
Ein weiterer Vorteil benannter Typen besteht darin, dass der Compiler eine versehentliche Fehleingabe eines Eigenschaftsnamens abfangen kann. In den vorherigen Beispielen sind firstProd2
, secondProd2
und thirdProd2
als Instanzen desselben anonymen Typs gedacht. Wenn Sie jedoch versehentlich thirdProd2
auf eine der folgenden Arten deklarieren würden, würde sich dessen Typ von dem von firstProd2
und secondProd2
unterscheiden.
' Dim thirdProd2 = New With {Key .Name = "stapler", Key .Price = 5.09}
' Dim thirdProd2 = New With {Key .Name = "stapler", Key .Price = "5.09"}
' Dim thirdProd2 = New With {Key .Name = "stapler", .Price = 5.09}
Wichtiger ist, dass es Einschränkungen bei der Verwendung anonymer Typen gibt, die nicht für Instanzen von benannten Typen gelten.
firstProd2
, secondProd2
und thirdProd2
sind Instanzen desselben anonymen Typs. Der Name für den freigegebenen anonymen Typ ist jedoch nicht verfügbar und kann nicht angezeigt werden, wo ein Typname in Ihrem Code erwartet wird. Beispielsweise kann ein anonymer Typ nicht verwendet werden, um eine Methodensignatur zu definieren, eine andere Variable oder ein anderes Feld oder in einer Typdeklaration zu deklarieren. Daher sind anonyme Typen nicht geeignet, wenn Sie Informationen über Methoden hinweg freigeben müssen.
Anonyme Typdefinition
Als Reaktion auf die Deklaration einer Instanz eines anonymen Typs erstellt der Compiler eine neue Klassendefinition, die die angegebenen Eigenschaften enthält.
Wenn der anonyme Typ mindestens eine Schlüsseleigenschaft enthält, überschreibt die Definition drei Elemente, die von Object geerbt wurden: Equals, GetHashCode und ToString. Der zum Testen der Gleichheit erstellte Code und die Bestimmung des Hashcodewerts berücksichtigt nur die Schlüsseleigenschaften. Wenn der anonyme Typ keine Schlüsseleigenschaften enthält, wird nur ToString überschrieben. Explizit benannte Eigenschaften eines anonymen Typs können nicht mit diesen generierten Methoden in Konflikt geraten. Das heißt, Sie können .Equals
, .GetHashCode
oder .ToString
nicht verwenden, um eine Eigenschaft zu benennen.
Anonyme Typdefinitionen mit mindestens einer Schlüsseleigenschaft implementieren auch die System.IEquatable<T> Schnittstelle, wobei T
der Typ des anonymen Typs ist.
Weitere Informationen zum vom Compiler erstellten Code und zur Funktionalität der überschriebenen Methoden finden Sie unter Anonyme Typdefinition.