Partilhar via


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 para Name é atribuído para cust8, e um valor inicializado é atribuído em cust9.

    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 e cust4 para declarar e inicializar cust10 e cust11.

    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 propriedades City e State, e a Customer classe tem uma Address propriedade que é uma instância de AddressClass.

    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.

Consulte também