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 Newangegeben 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 cust6Customer.

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ür Name für cust8zugewiesen, und ein initialisierter Wert wird in cust9 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 und cust4 verwendet, um und cust10zu 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 und Statedie 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, 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 Cityerstellt 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.

Siehe auch