Objektinitialisierer: Benannte und anonyme Typen (Visual Basic)
Durch Objektinitialisierer können mithilfe eines einzelnen Ausdrucks die Eigenschaften für ein komplexes Objekt angegeben werden. Sie können verwendet werden, um Instanzen von benannten Typen und anonymen Typen zu erstellen.
Deklarationen
Deklarationen von Instanzen benannter und anonymer Typen können fast identisch aussehen. Ihre Auswirkungen sind jedoch unterschiedlich. Jede Kategorie verfügt über eigene Möglichkeiten und Einschränkungen. Im folgenden Beispiel wird eine einfache Möglichkeit gezeigt, unter Verwendung einer Objektinitialisiererliste eine Instanz einer benannten Klasse, der Customer-Klasse, zu deklarieren und zu initialisieren. 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 einschließen.
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. Die Deklaration erstellt eine Instanz dieser Klasse. Für anonymousCust definiert der Compiler eine neue Klasse mit einer Eigenschaft, einer Zeichenfolge mit dem Namen Name, und erstellt eine neue Instanz dieser Klasse.
Benannte Typen
Objektinitialisierer bieten eine einfache Möglichkeit, den Konstruktor eines Typs aufzurufen und die Werte einiger oder aller Eigenschaften in einer einzigen Anweisung festzulegen. Der Compiler ruft den entsprechenden Konstruktor für die Anweisung auf: den Standardkonstruktor, wenn keine Argumente angegeben werden, oder einen parametrisierten Konstruktor, wenn mindestens ein Argument übergeben wird. Anschließend 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 bei der Definition der Klasse bestimmt. In den folgenden Beispielen muss die Customer-Klasse vorhanden sein. Diese muss über Member mit Namen Name und City verfügen, die Zeichenfolgenwerte akzeptieren.
Dim cust0 As Customer = New Customer With {.Name = "Toni Poe",
.City = "Louisville"}
Alternativ erhalten Sie das gleiche Ergebnis, indem Sie den folgenden Code verwenden:
Dim cust1 As New Customer With {.Name = "Toni Poe",
.City = "Louisville"}
Jede dieser Deklarationen entspricht dem folgenden Beispiel, in dem mithilfe des Standardkonstruktors ein Customer-Objekt erzeugt wird und dann unter Verwendung einer With-Anweisung Anfangswerte für die Name-Eigenschaft und die City-Eigenschaft angegeben werden.
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 beispielsweise ein Wert für Name festgelegt werden kann, können Sie ein Customer-Objekt auch folgendermaßen 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"}
Wie folgender Code zeigt, müssen Sie nicht alle Eigenschaften initialisieren.
Dim cust5 As Customer = New Customer With {.Name = "Toni Poe"}
Die Initialisierungsliste darf jedoch nicht leer sein. Nicht initialisierte Eigenschaften behalten ihre Standardwerte.
Typrückschluss mit benannten Typen
Sie können den Code für die Deklaration von cust1 verkürzen, indem Sie Objektinitialisierer und lokalen Typrückschluss kombinieren. Dadurch können Sie auf die As-Klausel in der Variablendeklaration verzichten. Der Datentyp der Variablen wird vom Typ des von der Zuweisung erstellten Objekts abgeleitet. Im folgenden Beispiel ist cust6 vom Typ Customer.
Dim cust6 = New Customer With {.Name = "Toni Poe",
.City = "Louisville"}
Hinweise zu benannten Typen
Ein Klassenmember kann nicht mehr als einmal 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, wie in der folgenden Deklaration für cust8, auf einen Member zugegriffen wird, bevor er initialisiert wurde, wird der Standardwert verwendet. Beachten Sie, dass bei der Verarbeitung einer Deklaration, die einen Objektinitialisierer verwendet, als erstes der entsprechende Konstruktor aufgerufen wird. Danach werden die einzelnen Felder in der Initialisiererliste initialisiert. In den folgenden Beispielen wird der Standardwert für Name für cust8 zugewiesen, und cust9 wird ein initialisierter Wert 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 aus cust3 und cust4 verwendet, um cust10 und cust11 zu deklarieren und zu initialisieren.
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 AddressClass eine Klasse mit zwei Eigenschaften, City und State. Die Customer-Klasse verfügt über eine Address-Eigenschaft, die eine Instanz von AddressClass 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, kann nicht vom Typ Object sein.
Klassenmember, die initialisiert werden, können keine freigegebenen Member, schreibgeschützten Member, Konstanten oder Methodenaufrufe sein.
Klassenmember, die initialisiert werden, können nicht indiziert oder qualifiziert werden. In den folgenden Beispielen werden Compilerfehler ausgelöst:
'' 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 entsprechend den Eigenschaften, die Sie in der Objektinitialisiererliste festlegen. Da der Name des Typs nicht angegeben wird, wird er als anonymer Typ bezeichnet. Vergleichen Sie die folgende Deklaration z. B. mit der früheren für cust6.
Dim cust13 = New With {.Name = "Toni Poe",
.City = "Louisville"}
Der einzige syntaktische Unterschied besteht darin, dass nach New kein Name für den Datentyp angegeben wird. Es geschieht jedoch etwas ganz anderes. Vom Compiler wird ein neuer anonymer Typ definiert, der über zwei Eigenschaften, Name und City, verfügt. Dann wird mit den angegebenen Werten eine Instanz davon erstellt. Im Beispiel werden die Typen von Name und City per Typrückschluss als Zeichenfolgen bestimmt.
Warnung
Der Name des anonymen Typs wird vom Compiler erzeugt und kann von Kompilierung zu Kompilierung variieren. Sie sollten im Code den Namen eines anonymen Typs nicht verwenden oder sich darauf verlassen.
Da der Name des Typs nicht verfügbar ist, können Sie keine As-Klausel verwenden, um cust13 zu deklarieren. Der Typ muss abgeleitet werden. Ohne die Verwendung später Bindung wird dadurch die Verwendung anonymer Typen auf lokale Variablen eingeschränkt.
Anonyme Typen unterstützen LINQ-Abfragen. Weitere Informationen zur Verwendung anonymer Typen in Abfragen finden Sie unter Anonyme Typen (Visual Basic) und Einführung in LINQ in Visual Basic.
Hinweise zu anonymen Typen
In der Regel sind alle bzw. die meisten Eigenschaften in einer Deklaration von anonymen Typen Schlüsseleigenschaften, die durch das Schlüsselwort Key vor dem Eigenschaftennamen gekennzeichnet werden.
Dim anonymousCust1 = New With {Key .Name = "Hugo Garcia", Key .City = "Louisville"}
Weitere Informationen zu Schlüsseleigenschaften finden Sie unter Key (Visual Basic).
Wie bei benannten Typen müssen Initialisiererlisten für anonyme Typdefinitionen mindestens eine Eigenschaft deklarieren.
Dim anonymousCust = New With {.Name = "Hugo Garcia"}
Wenn eine Instanz eines anonymen Typs deklariert wird, generiert der Compiler eine entsprechende anonyme Typdefinition. Die Namen und Datentypen der Eigenschaften werden aus der Deklaration der Instanz übernommen und vom Compiler in die Definition eingefügt. Die Eigenschaften werden nicht im Voraus benannt und definiert, wie dies bei einem benannten Typ der Fall wäre. Ihre Typen werden abgeleitet. Sie können die Datentypen der Eigenschaften nicht durch Verwendung einer As-Klausel angeben.
Anonyme Typen können die Namen und Werte ihrer Eigenschaften auch auf andere Weisen bestimmen. Beispielsweise kann eine Eigenschaft eines anonymen Typs sowohl den Namen als auch den Wert einer Variablen oder aber 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 über die Optionen zum Definieren von Eigenschaften in anonymen Typen finden Sie unter Gewusst wie: Ableiten von Eigenschaftennamen und Typen in Deklarationen von anonymen Typen (Visual Basic).
Siehe auch
Aufgaben
Gewusst wie: Deklarieren einer Instanz eines anonymen Typs (Visual Basic)
Gewusst wie: Deklarieren eines Objekts mithilfe eines Objektinitialisierers (Visual Basic)
Referenz
Konzepte
Lokaler Typrückschluss (Visual Basic)
Einführung in LINQ in Visual Basic
Benannte Typen im Vergleich zu anonymen Typen (Visual Basic)