Inicializadores de objeto: tipos nomeados e anônimos (Visual Basic)
Os inicializadores de objeto permitem especificar propriedades para um objeto complexo usando uma única expressão. Eles podem ser usados para criar instâncias de tipos nomeados e de tipos anônimos.
Declarations
As declarações de instâncias de tipos nomeados e anónimos podem parecer quase idênticas, mas os seus efeitos não são os mesmos. Cada categoria tem habilidades e restrições próprias. O exemplo a seguir mostra uma maneira conveniente de declarar e inicializar uma instância de uma classe nomeada, Customer
, usando uma lista de inicializadores de objetos. Observe que o nome da classe é especificado após a palavra-chave New
.
Dim namedCust = New Customer With {.Name = "Terry Adams"}
Um tipo anônimo não tem nome utilizável. Portanto, uma instanciação de um tipo anônimo não pode incluir um nome de classe.
Dim anonymousCust = New With {.Name = "Hugo Garcia"}
Os requisitos e os resultados das duas declarações não são os mesmos. Para namedCust
, uma Customer
classe que tem uma Name
propriedade já deve existir, e a declaração cria uma instância dessa classe. Para anonymousCust
, o compilador define uma nova classe que tem uma propriedade, uma cadeia de caracteres chamada Name
, e cria uma nova instância dessa classe.
Tipos nomeados
Os inicializadores de objeto fornecem uma maneira simples de chamar o construtor de um tipo e, em seguida, definir os valores de algumas ou todas as propriedades em uma única instrução. O compilador invoca o construtor apropriado para a instrução: o construtor sem parâmetros se nenhum argumento for apresentado, ou um construtor parametrizado se um ou mais argumentos forem enviados. Depois disso, as propriedades especificadas são inicializadas na ordem em que são apresentadas na lista de inicializadores.
Cada inicialização na lista de inicializadores consiste na atribuição de um valor inicial a um membro da classe. Os nomes e tipos de dados dos membros são determinados quando a classe é definida. Nos exemplos a seguir, a Customer
classe deve existir e deve ter membros nomeados Name
e City
que possam aceitar valores de cadeia de caracteres.
Dim cust0 As Customer = New Customer With {.Name = "Toni Poe",
.City = "Louisville"}
Como alternativa, você pode obter o mesmo resultado usando o seguinte código:
Dim cust1 As New Customer With {.Name = "Toni Poe",
.City = "Louisville"}
Cada uma dessas declarações é equivalente ao exemplo a seguir, que cria um Customer
objeto usando o construtor sem parâmetros e, em seguida, especifica valores iniciais para as Name
propriedades e City
usando uma With
instrução.
Dim cust2 As New Customer()
With cust2
.Name = "Toni Poe"
.City = "Louisville"
End With
Se a Customer
classe contém um construtor parametrizado que permite enviar um valor para Name
, por exemplo, você também pode declarar e inicializar um Customer
objeto das seguintes maneiras:
Dim cust3 As Customer =
New Customer("Toni Poe") With {.City = "Louisville"}
' --or--
Dim cust4 As New Customer("Toni Poe") With {.City = "Louisville"}
Não é necessário inicializar todas as propriedades, como mostra o código a seguir.
Dim cust5 As Customer = New Customer With {.Name = "Toni Poe"}
No entanto, a lista de inicialização não pode estar vazia. As propriedades não inicializadas mantêm seus valores padrão.
Inferência de tipo com tipos nomeados
Você pode encurtar o código para a declaração de combinando inicializadores de objeto e inferência de cust1
tipo local. Isso permite que você omita a As
cláusula na declaração de variável. O tipo de dados da variável é inferido a partir do tipo do objeto que é criado pela atribuição. No exemplo a seguir, o tipo de cust6
é Customer
.
Dim cust6 = New Customer With {.Name = "Toni Poe",
.City = "Louisville"}
Comentários sobre tipos nomeados
Um membro de classe não pode ser inicializado mais de uma vez na lista de inicializadores de objetos. A declaração de
cust7
causa um erro.'' This code does not compile because Name is initialized twice. ' Dim cust7 = New Customer With {.Name = "Toni Poe", ' .City = "Louisville", ' .Name = "Blue Yonder Airlines"}
Um membro pode ser usado para inicializar a si mesmo ou outro campo. Se um membro for acessado antes de ter sido inicializado, como na declaração a seguir para
cust8
, o valor padrão será usado. Lembre-se de que quando uma declaração que usa um inicializador de objeto é processada, a primeira coisa que acontece é que o construtor apropriado é invocado. Depois disso, os campos individuais na lista de inicializadores são inicializados. Nos exemplos a seguir, o valor padrão paraName
é atribuído paracust8
, e um valor inicializado é atribuído emcust9
.Dim cust8 = New Customer With {.Name = .Name & ", President"} Dim cust9 = New Customer With {.Name = "Toni Poe", .Title = .Name & ", President"}
O exemplo a seguir usa o construtor parametrizado de
cust3
ecust4
para declarar e inicializarcust10
ecust11
.Dim cust10 = New Customer("Toni Poe") With {.Name = .Name & ", President"} ' --or-- Dim cust11 As New Customer("Toni Poe") With {.Name = .Name & ", President"}
Os inicializadores de objeto podem ser aninhados. No exemplo a seguir,
AddressClass
é uma classe que tem duas propriedadesCity
eState
, e aCustomer
classe tem umaAddress
propriedade que é uma instância deAddressClass
.Dim cust12 = New Customer With {.Name = "Toni Poe", .Address = New AddressClass With {.City = "Louisville", .State = "Kentucky"}} Console.WriteLine(cust12.Address.State)
A lista de inicialização não pode estar vazia.
A instância que está sendo inicializada não pode ser do tipo Object.
Os membros da classe que estão sendo inicializados não podem ser membros compartilhados, membros somente leitura, constantes ou chamadas de método.
Os membros da classe que estão sendo inicializados não podem ser indexados ou qualificados. Os exemplos a seguir geram erros do compilador:
'' Not valid.
' Dim c1 = New Customer With {.OrderNumbers(0) = 148662}
' Dim c2 = New Customer with {.Address.City = "Springfield"}
Tipos Anônimos
Os tipos anônimos usam inicializadores de objeto para criar instâncias de novos tipos que você não define e nomeia explicitamente. Em vez disso, o compilador gera um tipo de acordo com as propriedades que você designa na lista de inicializadores de objetos. Como o nome do tipo não é especificado, ele é chamado de tipo anônimo. Por exemplo, compare a seguinte declaração com a anterior para cust6
.
Dim cust13 = New With {.Name = "Toni Poe",
.City = "Louisville"}
A única diferença sintaticamente é que nenhum nome é especificado depois New
para o tipo de dados. No entanto, o que acontece é bem diferente. O compilador define um novo tipo anônimo que tem duas propriedades Name
e City
, e cria uma instância dele com os valores especificados. A inferência de tipo determina os tipos de Name
e City
no exemplo a serem strings.
Atenção
O nome do tipo anônimo é gerado pelo compilador e pode variar de compilação para compilação. Seu código não deve usar ou confiar no nome de um tipo anônimo.
Como o nome do tipo não está disponível, não é possível usar uma As
cláusula para declarar cust13
. O seu tipo deve ser inferido. Sem usar a vinculação tardia, isso limita o uso de tipos anônimos a variáveis locais.
Os tipos anônimos fornecem suporte crítico para consultas LINQ. Para obter mais informações sobre o uso de tipos anônimos em consultas, consulte Tipos anônimos e Introdução ao LINQ no Visual Basic.
Comentários sobre tipos anônimos
Normalmente, todas ou a maioria das propriedades em uma declaração de tipo anônimo serão propriedades de chave, que são indicadas digitando a palavra-chave
Key
na frente do nome da propriedade.Dim anonymousCust1 = New With {Key .Name = "Hugo Garcia", Key .City = "Louisville"}
Para obter mais informações sobre propriedades de chave, consulte Chave.
Como os tipos nomeados, as listas de inicializadores para definições de tipo anônimo devem declarar pelo menos uma propriedade.
Dim anonymousCust = New With {.Name = "Hugo Garcia"}
Quando uma instância de um tipo anônimo é declarada, o compilador gera uma definição de tipo anônimo correspondente. Os nomes e tipos de dados das propriedades são retirados da declaração de instância e são incluídos pelo compilador na definição. As propriedades não são nomeadas e definidas antecipadamente, como seriam para um tipo nomeado. Seus tipos são inferidos. Não é possível especificar os tipos de dados das propriedades usando uma
As
cláusula.Os tipos anônimos também podem estabelecer os nomes e valores de suas propriedades de várias outras maneiras. Por exemplo, uma propriedade de tipo anônimo pode tomar o nome e o valor de uma variável ou o nome e o valor de uma propriedade de outro objeto.
' 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}
Para obter mais informações sobre as opções para definir propriedades em tipos anônimos, consulte Como inferir nomes e tipos de propriedade em declarações de tipo anônimo.