Инициализаторы объектов: именованные и анонимные типы (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, то будет использовано значение по умолчанию. Помните, что при обработке объявления, использующего инициализатор объекта, в первую очередь происходит вызов соответствующего конструктора. После этого инициализируются отдельные поля в списке инициализаторов. В следующих примерах параметру Name присваивается значение по умолчанию cust8, а инициализированное значение присваивается 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 и State, а класс Customer имеет свойство 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 не указано имя типа данных. Однако выполняемые действия сильно отличаются. Компилятор определяет новый анонимный тип, который имеет два свойства (Name и City) и создает экземпляр этого типа с указанными значениями. Вывод типа определяет типы Name и City (в этом примере это строки).

Предупреждение

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

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

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

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

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

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

    Дополнительные сведения о ключевых свойствах см. в разделе Key (Visual Basic).

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

    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}
    

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

См. также

Задачи

Практическое руководство. Выведение имен свойств и типов в объявлениях анонимных типов (Visual Basic)

Практическое руководство. Объявление объекта с помощью инициализатора объектов (Visual Basic)

Ссылки

Key (Visual Basic)

Основные понятия

Вывод локального типа (Visual Basic)

Анонимные типы (Visual Basic)

Знакомство с LINQ в Visual Basic