Objektinitialisierer: Benannte und anonyme Typen (Visual Basic)
Mit Objektinitialisierern können Sie Eigenschaften für ein komplexes Objekt mithilfe eines einzelnen Ausdrucks angeben. Sie können verwendet werden, um Instanzen von benannten und anonymen Typen zu erstellen.
Deklarationen
Deklarationen von Instanzen von benannten und anonymen Typen können fast identisch aussehen, aber ihre Auswirkungen sind nicht identisch. Jede Kategorie verfügt über eigene Fähigkeiten und Einschränkungen. Das folgende Beispiel zeigt eine praktische Möglichkeit zum Deklarieren und Initialisieren einer Instanz einer benannten Klasse( Customer
) mithilfe einer Objektinitialisiererliste. Beachten Sie, dass der Name der Klasse nach dem Schlüsselwort New
angegeben wird.
Dim namedCust = New Customer With {.Name = "Terry Adams"}
Ein anonymer Typ hat keinen verwendbaren Namen. Daher kann eine Instanziierung eines anonymen Typs keinen Klassennamen enthalten.
Dim anonymousCust = New With {.Name = "Hugo Garcia"}
Die Anforderungen und Ergebnisse der beiden Deklarationen sind nicht identisch. Für namedCust
muss bereits eine Customer
-Klasse mit einer Name
-Eigenschaft vorhanden sein, und die Deklaration erstellt eine Instanz dieser Klasse. Für anonymousCust
definiert der Compiler eine neue Klasse mit einer Eigenschaft, einer Zeichenfolge namens Name
, und erstellt eine neue Instanz dieser Klasse.
Benannte Typen
Objektinitialisierer bieten eine einfache Möglichkeit, den Konstruktor eines Typs aufzurufen und dann die Werte einiger oder aller Eigenschaften in einer einzelnen Anweisung festzulegen. Der Compiler ruft den entsprechenden Konstruktor für die Anweisung auf: den parameterlosen Konstruktor, wenn keine Argumente angezeigt werden, oder einen parametrisierten Konstruktor, wenn ein oder mehrere Argumente gesendet werden. Danach werden die angegebenen Eigenschaften in der Reihenfolge initialisiert, in der sie in der Initialisiererliste angezeigt werden.
Jede Initialisierung in der Initialisiererliste besteht aus der Zuweisung eines Anfangswerts zu einem Member der -Klasse. Die Namen und Datentypen der Member werden bestimmt, wenn die -Klasse definiert wird. In den folgenden Beispielen muss die Customer
-Klasse vorhanden sein, und sie muss Über Member namens Name
und City
verfügen, die Zeichenfolgenwerte akzeptieren können.
Dim cust0 As Customer = New Customer With {.Name = "Toni Poe",
.City = "Louisville"}
Alternativ können Sie dasselbe Ergebnis mithilfe des folgenden Codes erhalten:
Dim cust1 As New Customer With {.Name = "Toni Poe",
.City = "Louisville"}
Jede dieser Deklarationen entspricht dem folgenden Beispiel, das mithilfe des parameterlosen Konstruktors ein Customer
-Objekt erstellt und dann die Anfangswerte für die Eigenschaften Name
und City
mithilfe einer With
-Anweisung angibt.
Dim cust2 As New Customer()
With cust2
.Name = "Toni Poe"
.City = "Louisville"
End With
Wenn die Customer
-Klasse einen parametrisierten Konstruktor enthält, mit dem Sie z. B. einen Wert für Name
senden können, können Sie ein Customer
-Objekt auch auf folgende Weise deklarieren und initialisieren:
Dim cust3 As Customer =
New Customer("Toni Poe") With {.City = "Louisville"}
' --or--
Dim cust4 As New Customer("Toni Poe") With {.City = "Louisville"}
Sie müssen nicht alle Eigenschaften initialisieren, wie der folgende Code zeigt.
Dim cust5 As Customer = New Customer With {.Name = "Toni Poe"}
Die Initialisierungsliste darf jedoch nicht leer sein. Nicht initialisierte Eigenschaften behalten ihre Standardwerte bei.
Typrückschluss mit benannten Typen
Sie können den Code für die Deklaration von cust1
kürzen, indem Sie Objektinitialisierer und lokale Typrückschlüsse kombinieren. Dadurch können Sie die As
-Klausel in der Variablendeklaration weglassen. Der Datentyp der Variablen wird aus dem Typ des Objekts abgeleitet, das von der Zuweisung erstellt wird. Im folgenden Beispiel lautet der Typ von cust6
Customer
.
Dim cust6 = New Customer With {.Name = "Toni Poe",
.City = "Louisville"}
Hinweise zu benannten Typen
Ein Klassenmember kann nicht mehrmals in der Objektinitialisiererliste initialisiert werden. Die Deklaration von
cust7
verursacht einen Fehler.'' This code does not compile because Name is initialized twice. ' Dim cust7 = New Customer With {.Name = "Toni Poe", ' .City = "Louisville", ' .Name = "Blue Yonder Airlines"}
Ein Member kann verwendet werden, um sich selbst oder ein anderes Feld zu initialisieren. Wenn auf ein Element zugegriffen wird, bevor es initialisiert wurde, wie in der folgenden Deklaration für
cust8
, wird der Standardwert verwendet. Denken Sie daran, dass beim Verarbeiten einer Deklaration, die einen Objektinitialisierer verwendet, zuerst der entsprechende Konstruktor aufgerufen wird. Danach werden die einzelnen Felder in der Initialisiererliste initialisiert. In den folgenden Beispielen wird der Standardwert fürName
fürcust8
zugewiesen, und ein initialisierter Wert wird incust9
zugewiesen.Dim cust8 = New Customer With {.Name = .Name & ", President"} Dim cust9 = New Customer With {.Name = "Toni Poe", .Title = .Name & ", President"}
Im folgenden Beispiel wird der parametrisierte Konstruktor von
cust3
undcust4
verwendet, um undcust10
zu deklarieren und zu initialisierencust11
.Dim cust10 = New Customer("Toni Poe") With {.Name = .Name & ", President"} ' --or-- Dim cust11 As New Customer("Toni Poe") With {.Name = .Name & ", President"}
Objektinitialisierer können geschachtelt werden. Im folgenden Beispiel ist eine Klasse,
AddressClass
die über zwei Eigenschaften verfügt,City
undState
dieCustomer
-Klasse verfügt über eineAddress
-Eigenschaft, die eine Instanz vonAddressClass
ist.Dim cust12 = New Customer With {.Name = "Toni Poe", .Address = New AddressClass With {.City = "Louisville", .State = "Kentucky"}} Console.WriteLine(cust12.Address.State)
Die Initialisierungsliste darf nicht leer sein.
Die Instanz, die initialisiert wird, darf nicht vom Typ Object sein.
Klassenmember, die initialisiert werden, dürfen nicht freigegebene Member, schreibgeschützte Member, Konstanten oder Methodenaufrufe sein.
Klassenmember, die initialisiert werden, können nicht indiziert oder qualifiziert werden. Die folgenden Beispiele lösen Compilerfehler aus:
'' Not valid.
' Dim c1 = New Customer With {.OrderNumbers(0) = 148662}
' Dim c2 = New Customer with {.Address.City = "Springfield"}
Anonyme Typen
Anonyme Typen verwenden Objektinitialisierer, um Instanzen neuer Typen zu erstellen, die Sie nicht explizit definieren und benennen. Stattdessen generiert der Compiler einen Typ gemäß den Eigenschaften, die Sie in der Objektinitialisiererliste angeben. Da der Name des Typs nicht angegeben ist, wird er als anonymer Typ bezeichnet. Vergleichen Sie z. B. die folgende Deklaration mit der früheren Deklaration für cust6
.
Dim cust13 = New With {.Name = "Toni Poe",
.City = "Louisville"}
Der einzige syntaktische Unterschied besteht darin, dass kein Name nach New
für den Datentyp angegeben wird. Allerdings ist das, was passiert, ganz anders. Der Compiler definiert einen neuen anonymen Typ, der über zwei Eigenschaften verfügt, Name
und City
erstellt eine Instanz davon mit den angegebenen Werten. Der Typrückschluss bestimmt die Typen von Name
und City
im Beispiel als Zeichenfolgen.
Achtung
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 davon abhängig sein.
Da der Name des Typs nicht verfügbar ist, können Sie keine As
-Klausel verwenden, um zu deklarieren cust13
. Der Typ muss abgeleitet werden. Ohne die Verwendung einer späten Bindung wird die Verwendung anonymer Typen auf lokale Variablen beschränkt.
Anonyme Typen bieten wichtige Unterstützung für LINQ-Abfragen. Weitere Informationen zur Verwendung anonymer Typen in Abfragen finden Sie unter Anonyme Typen und Einführung in LINQ in Visual Basic.
Informationen über anonyme Typen
In der Regel handelt es sich bei allen oder den meisten Eigenschaften in einer anonymen Typdeklaration um Schlüsseleigenschaften, die durch Eingabe des Schlüsselwort (keyword)
Key
vor dem Eigenschaftennamen angegeben werden.Dim anonymousCust1 = New With {Key .Name = "Hugo Garcia", Key .City = "Louisville"}
Weitere Informationen zu Schlüsseleigenschaften finden Sie unter Key.
Wie benannte Typen müssen Initialisiererlisten für anonyme Typdefinitionen mindestens eine Eigenschaft deklarieren.
Dim anonymousCust = New With {.Name = "Hugo Garcia"}
Wenn ein instance eines anonymen Typs deklariert wird, generiert der Compiler eine entsprechende anonyme Typdefinition. Die Namen und Datentypen der Eigenschaften stammen aus der instance-Deklaration und werden vom Compiler in die Definition eingeschlossen. Die Eigenschaften werden nicht im Voraus benannt und definiert, wie sie für einen benannten Typ wären. Ihre Typen werden abgeleitet. Sie können die Datentypen der Eigenschaften nicht mithilfe einer
As
-Klausel angeben.Anonyme Typen können die Namen und Werte ihrer Eigenschaften auch auf verschiedene andere Weise festlegen. Beispielsweise kann eine anonyme Typeigenschaft sowohl den Namen und den Wert einer Variablen als auch den Namen und den Wert einer Eigenschaft eines anderen Objekts annehmen.
' Create a variable, Name, and give it an initial value. Dim Name = "Hugo Garcia" ' Variable anonymousCust2 will have one property, Name, with ' "Hugo Garcia" as its initial value. Dim anonymousCust2 = New With {Key Name} ' The next declaration uses a property from namedCust, defined ' in an earlier example. After the declaration, anonymousCust3 will ' have one property, Name, with "Terry Adams" as its value. Dim anonymousCust3 = New With {Key namedCust.Name}
Weitere Informationen zu den Optionen zum Definieren von Eigenschaften in anonymen Typen finden Sie unter Gewusst wie: Ableiten von Eigenschaftsnamen und -typen in anonymen Typdeklarationen.