Поделиться через


Инициализаторы объектов: именованные и анонимные типы (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.

    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. Дополнительные сведения об использовании анонимных типов в запросах см. в статье "Анонимные типы " и "Введение в 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}
    

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

См. также