Udostępnij za pośrednictwem


Inicjatory obiektów: typy nazwane i anonimowe (Visual Basic)

Inicjatory obiektów umożliwiają określanie właściwości obiektu złożonego przy użyciu pojedynczego wyrażenia. Mogą być używane do tworzenia wystąpień typów nazwanych i anonimowych.

Deklaracje

Deklaracje wystąpień nazwanych i anonimowych typów mogą wyglądać niemal identycznie, ale ich skutki nie są takie same. Każda kategoria ma własne możliwości i ograniczenia. W poniższym przykładzie pokazano wygodny sposób deklarowania i inicjowania wystąpienia nazwanej klasy , Customerprzy użyciu listy inicjatora obiektów. Zwróć uwagę, że nazwa klasy jest określona po słowie kluczowym New.

Dim namedCust = New Customer With {.Name = "Terry Adams"}

Typ anonimowy nie ma nazwy użytecznej. W związku z tym wystąpienie typu anonimowego nie może zawierać nazwy klasy.

Dim anonymousCust = New With {.Name = "Hugo Garcia"}

Wymagania i wyniki tych dwóch deklaracji nie są takie same. W przypadku namedCust, klasa Customer, która ma właściwość Name, musi już istnieć, a deklaracja tworzy wystąpienie tej klasy. W przypadku anonymousCustprogramu kompilator definiuje nową klasę, która ma jedną właściwość, ciąg o nazwie Namei tworzy nowe wystąpienie tej klasy.

Typy nazwane

Inicjatory obiektów zapewniają prosty sposób wywoływania konstruktora typu, a następnie ustawiania wartości niektórych lub wszystkich właściwości w jednej instrukcji. Kompilator wywołuje odpowiedni konstruktor dla instrukcji: konstruktor bez parametrów, jeśli nie są prezentowane żadne argumenty, lub konstruktor sparametryzowany, jeśli jeden lub więcej argumentów jest wysyłanych. Następnie określone właściwości są inicjowane w kolejności, w której są prezentowane na liście inicjalizatorów.

Każda inicjalizacja na liście inicjalizacyjnej składa się z przypisania wartości początkowej do członka klasy. Nazwy i typy danych składowych są określane podczas definiowania klasy. W poniższych przykładach Customer klasa musi istnieć i musi mieć elementy członkowskie o nazwie Name i City które mogą akceptować wartości ciągów.

Dim cust0 As Customer = New Customer With {.Name = "Toni Poe", 
                                           .City = "Louisville"}

Alternatywnie możesz uzyskać ten sam wynik, używając następującego kodu:

Dim cust1 As New Customer With {.Name = "Toni Poe", 
                                .City = "Louisville"}

Każda z tych deklaracji jest równoważna poniższemu przykładowi, który tworzy Customer obiekt przy użyciu konstruktora bez parametrów, a następnie określa początkowe wartości właściwości Name i City przy użyciu With instrukcji .

Dim cust2 As New Customer()
With cust2
    .Name = "Toni Poe"
    .City = "Louisville"
End With

Customer Jeśli klasa zawiera sparametryzowany konstruktor, który umożliwia przekazywanie wartości dla Name, można na przykład zadeklarować i zainicjować obiekt Customer w następujące sposoby:

Dim cust3 As Customer = 
    New Customer("Toni Poe") With {.City = "Louisville"}
' --or--
Dim cust4 As New Customer("Toni Poe") With {.City = "Louisville"}

Nie trzeba inicjować wszystkich właściwości, jak pokazano w poniższym kodzie.

Dim cust5 As Customer = New Customer With {.Name = "Toni Poe"}

Jednak lista inicjowania nie może być pusta. Niezainicjowane właściwości zachowują wartości domyślne.

Wnioskowanie typów przy użyciu nazwanych typów

Kod deklaracji cust1 można skrócić, łącząc inicjatory obiektów i wnioskowanie typu lokalnego. Dzięki temu można pominąć klauzulę As w deklaracji zmiennej. Typ danych zmiennej jest wnioskowany z typu obiektu utworzonego przez przypisanie. W poniższym przykładzie typem cust6 jest Customer.

Dim cust6 = New Customer With {.Name = "Toni Poe", 
                               .City = "Louisville"}

Uwagi dotyczące nazwanych typów

  • Nie można zainicjować składowej klasy więcej niż jeden raz na liście inicjatorów obiektów. Deklaracja cust7 powoduje błąd.

    '' This code does not compile because Name is initialized twice.
    ' Dim cust7 = New Customer With {.Name = "Toni Poe", 
    '                                .City = "Louisville",
    '                                .Name = "Blue Yonder Airlines"}
    
  • Członek może być użyty do inicjalizacji samego siebie lub innego pola. Jeśli dostęp do elementu członkowskiego jest uzyskiwany przed jego zainicjowaniem, jak w poniższej deklaracji dla cust8, zostanie użyta wartość domyślna. Pamiętaj, że gdy deklaracja używająca inicjatora obiektu jest przetwarzana, pierwszą rzeczą, która się dzieje, jest wywoływanie odpowiedniego konstruktora. Następnie poszczególne pola w liście inicjalizacyjnej są inicjalizowane. W poniższych przykładach wartość domyślna dla Name jest przypisywana do cust8, a zainicjowana wartość jest przypisywana w cust9.

    Dim cust8 = New Customer With {.Name = .Name & ", President"}
    Dim cust9 = New Customer With {.Name = "Toni Poe", 
                                   .Title = .Name & ", President"}
    

    W poniższym przykładzie użyto sparametryzowanego konstruktora z cust3 i cust4 do deklarowania i inicjowania cust10 i cust11.

    Dim cust10 = New Customer("Toni Poe") With {.Name = .Name & ", President"}
    ' --or--
    Dim cust11 As New Customer("Toni Poe") With {.Name = .Name & ", President"}
    
  • Inicjalizatory obiektów można zagnieżdżać. W poniższym przykładzie AddressClass to klasa, która ma dwie właściwości: City i State, a klasa Customer ma właściwość Address, która jest wystąpieniem klasy AddressClass.

    Dim cust12 = 
        New Customer With {.Name = "Toni Poe", 
                           .Address = 
                               New AddressClass With {.City = "Louisville", 
                                                      .State = "Kentucky"}}
    Console.WriteLine(cust12.Address.State)
    
  • Lista inicjowania nie może być pusta.

  • Zainicjowane wystąpienie nie może być typu Obiekt.

  • Inicjowane składowe klasy nie mogą być elementami współdzielonymi, elementami tylko do odczytu, stałymi ani wywołaniami metod.

  • Członkowie klasy, którzy są inicjalizowani, nie mogą być indeksowani ani kwalifikowani. W poniższych przykładach występują błędy kompilatora:

    '' Not valid.

    ' Dim c1 = New Customer With {.OrderNumbers(0) = 148662}

    ' Dim c2 = New Customer with {.Address.City = "Springfield"}

Typy anonimowe

Typy anonimowe używają inicjatorów obiektów, aby tworzyć wystąpienia nowych typów, które nie są jawnie zdefiniowane i nazywane. Zamiast tego kompilator generuje typ zgodnie z właściwościami wyznaczanymi na liście inicjatora obiektów. Ponieważ nazwa typu nie jest określona, jest nazywana typem anonimowym. Na przykład porównaj następującą deklarację z wcześniejszą dla cust6.

Dim cust13 = New With {.Name = "Toni Poe", 
                       .City = "Louisville"}

Jedyną różnicą jest to, że żadna nazwa nie jest określona po New dla typu danych. Jednak to, co się dzieje, jest zupełnie inne. Kompilator definiuje nowy typ anonimowy, który ma dwie właściwości, Name i City, i tworzy jego instancję z określonymi wartościami. Wnioskowanie typu określa typy Name i City w przykładzie jako ciągi.

Ostrzeżenie

Nazwa typu anonimowego jest generowana przez kompilator i może się różnić od kompilacji do kompilacji. Kod nie powinien używać ani polegać na nazwie typu anonimowego.

Ponieważ nazwa typu jest niedostępna, nie można użyć As klauzuli do zadeklarowania cust13. Jego typ musi być wywnioskowany. Bez użycia opóźnionego powiązania ogranicza to użycie typów anonimowych do zmiennych lokalnych.

Typy anonimowe zapewniają krytyczną obsługę zapytań LINQ. Aby uzyskać więcej informacji na temat używania typów anonimowych w zapytaniach, zobacz Typy anonimowe i Wprowadzenie do LINQ w Visual Basic.

Uwagi dotyczące typów anonimowych

  • Zazwyczaj wszystkie lub większość właściwości w deklaracji typu anonimowego będą właściwościami klucza, które są wskazywane przez wpisanie słowa kluczowego Key przed nazwą właściwości.

    
    Dim anonymousCust1 = New With {Key .Name = "Hugo Garcia", 
                                   Key .City = "Louisville"}
    

    Aby uzyskać więcej informacji na temat właściwości klucza, zobacz Klucz.

  • Podobnie jak nazwane typy, listy inicjatorów dla definicji typów anonimowych muszą zadeklarować co najmniej jedną właściwość.

    Dim anonymousCust = New With {.Name = "Hugo Garcia"}
    
  • Po zadeklarowaniu wystąpienia typu anonimowego kompilator generuje zgodną definicję typu anonimowego. Nazwy i typy danych właściwości są pobierane z deklaracji wystąpienia i są dołączane przez kompilator w definicji. Właściwości nie są nazwane i zdefiniowane z wyprzedzeniem, tak jak byłoby to w przypadku nazwanego typu. Ich typy są wnioskowane. Nie można określić typów danych właściwości przy użyciu klauzuli As .

  • Typy anonimowe mogą również określać nazwy i wartości swoich właściwości na kilka sposobów. Na przykład właściwość typu anonimowego może przyjmować zarówno nazwę, jak i wartość zmiennej albo nazwę i wartość właściwości innego obiektu.

    ' 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}
    

    Aby uzyskać więcej informacji na temat opcji definiowania właściwości w typach anonimowych, zobacz Jak wnioskować nazwy i typy właściwości w deklaracjach typów anonimowych.

Zobacz także