Инициализаторы объектов: именованные и анонимные типы (Visual Basic)

Инициализаторы объектов позволяют указать свойства сложного объекта с помощью одного выражения. Их можно использовать для создания экземпляров именованных типов и анонимных типов.

Объявления

Объявления экземпляров именованных и анонимных типов могут выглядеть почти одинаково, но их эффекты не совпадают. Каждая категория имеет собственные возможности и ограничения. В следующем примере показан удобный способ объявления и инициализации экземпляра именованного класса Customerс помощью списка инициализатора объектов. Обратите внимание, что имя класса указывается после ключевое словоNew.

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

Анонимный тип не имеет используемого имени. Поэтому экземпляр анонимного типа не может содержать имя класса.

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

Требования и результаты двух объявлений не совпадают. Для namedCustэтого Customer класса, имеющего Name свойство, уже должно существовать, и объявление создает экземпляр этого класса. Для anonymousCustэтого компилятор определяет новый класс с одним свойством, строковым именем Nameи создает новый экземпляр этого класса.

Именованные типы

Инициализаторы объектов предоставляют простой способ вызова конструктора типа, а затем задать значения некоторых или всех свойств в одной инструкции. Компилятор вызывает соответствующий конструктор для инструкции: конструктор без параметров, если аргументы не представлены, или параметризованный конструктор, если один или несколько аргументов отправляются. После этого указанные свойства инициализированы в порядке, в котором они представлены в списке инициализатора.

Каждая инициализация в списке инициализатора состоит из назначения начального значения члену класса. Имена и типы данных элементов определяются при определении класса. В следующих примерах Customer класс должен существовать и должен иметь элементы с именем Name и City принимать строковые значения.

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

Кроме того, вы можете получить тот же результат с помощью следующего кода:

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

Каждое из этих объявлений эквивалентно следующему примеру, который создает Customer объект с помощью конструктора без параметров, а затем задает начальные значения для Name свойств City с помощью инструкции With .

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

Customer Если класс содержит параметризованный конструктор, позволяющий отправлять значение, Nameнапример, можно объявить и инициализировать Customer объект следующим образом:

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

Не нужно инициализировать все свойства, как показано в следующем коде.

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

Однако список инициализации не может быть пустым. Неинициализированные свойства сохраняют значения по умолчанию.

Вывод типов с именованными типами

Вы можете сократить код объявления cust1 путем объединения инициализаторов объектов и вывода локальных типов. Это позволяет опущению As предложения в объявлении переменной. Тип данных переменной выводится из типа объекта, созданного назначением. В следующем примере тип cust6 имеет тип Customer.

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

Примечания о именованных типах

  • Член класса нельзя инициализировать несколько раз в списке инициализатора объектов. Объявление cust7 причин возникновения ошибки.

    '' This code does not compile because Name is initialized twice.
    ' Dim cust7 = New Customer With {.Name = "Toni Poe", 
    '                                .City = "Louisville",
    '                                .Name = "Blue Yonder Airlines"}
    
  • Элемент можно использовать для инициализации себя или другого поля. Если элемент доступен до инициализации, как показано в следующем объявлении, cust8будет использоваться значение по умолчанию. Помните, что при обработке объявления, использующего инициализатор объектов, первое, что происходит, заключается в том, что вызывается соответствующий конструктор. После этого отдельные поля в списке инициализатора инициализированы. В следующих примерах назначается cust8значение по умолчанию для Name инициализированного значенияcust9.

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

    В следующем примере используется параметризованный конструктор из cust3 и для объявления и cust4 инициализации cust10 и cust11.

    Dim cust10 = New Customer("Toni Poe") With {.Name = .Name & ", President"}
    ' --or--
    Dim cust11 As New Customer("Toni Poe") With {.Name = .Name & ", President"}
    
  • Инициализаторы объектов можно вложить. В следующем примере AddressClass — это класс, имеющий два свойства, City и StateCustomer класс имеет Address свойство, которое является экземпляромAddressClass.

    Dim cust12 = 
        New Customer With {.Name = "Toni Poe", 
                           .Address = 
                               New AddressClass With {.City = "Louisville", 
                                                      .State = "Kentucky"}}
    Console.WriteLine(cust12.Address.State)
    
  • Список инициализации не может быть пустым.

  • Экземпляр, инициализируемый, не может иметь тип Object.

  • Элементы класса, инициализированные не могут быть общими членами, элементами только для чтения, константами или вызовами методов.

  • Члены класса, инициализированные не могут быть индексированы или квалифицированы. В следующих примерах возникают ошибки компилятора:

    '' Not valid.

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

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

Анонимные типы

Анонимные типы используют инициализаторы объектов для создания экземпляров новых типов, которые не определяются явным образом и имена. Вместо этого компилятор создает тип в соответствии со свойствами, указанными в списке инициализатора объектов. Так как имя типа не указано, он называется анонимным типом. Например, сравните следующее объявление с предыдущим cust6для.

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

Единственное различие синтаксически заключается в том, что имя не указано после New типа данных. Тем не менее, что происходит совершенно другое. Компилятор определяет новый анонимный тип с двумя свойствами и NameCityсоздает экземпляр с указанными значениями. Вывод типов определяет типы Name строк и City в примере.

Внимание

Имя анонимного типа создается компилятором и может отличаться от компиляции до компиляции. Код не должен использовать или полагаться на имя анонимного типа.

Так как имя типа недоступно, нельзя использовать As предложение для объявления cust13. Его тип должен быть выведен. Без использования поздней привязки это ограничивает использование анонимных типов локальными переменными.

Анонимные типы обеспечивают критичную поддержку запросов LINQ. Дополнительные сведения об использовании анонимных типов в запросах см. в статье "Анонимные типы " и "Введение в LINQ" в Visual Basic.

Примечания об анонимных типах

  • Как правило, все или большинство свойств в объявлении анонимного типа будут ключевыми свойствами, которые указываются путем ввода ключевое слово Key перед именем свойства.

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

    Дополнительные сведения о свойствах ключей см. в разделе "Ключ".

  • Как и именованные типы, списки инициализаторов для определений анонимных типов должны объявлять по крайней мере одно свойство.

    Dim anonymousCust = New With {.Name = "Hugo Garcia"}
    
  • При объявлении экземпляра анонимного типа компилятор создает соответствующее определение анонимного типа. Имена и типы данных свойств взяты из объявления экземпляра и включаются компилятором в определение. Свойства не именуются и определяются заранее, так как они будут использоваться для именованного типа. Их типы выводятся. Нельзя указать типы данных свойств с помощью As предложения.

  • Анонимные типы также могут устанавливать имена и значения их свойств несколькими другими способами. Например, свойство анонимного типа может принимать как имя, так и значение переменной, или имя и значение свойства другого объекта.

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

    Дополнительные сведения о параметрах определения свойств в анонимных типах см. в разделе "Практическое руководство. Вывод имен свойств и типов в объявлениях анонимных типов".

См. также