Initialiseurs d'objets : types nommés et anonymes (Visual Basic)
Les initialiseurs d’objets vous permettent de spécifier des propriétés pour un objet complexe à l’aide d’une seule expression. Ils peuvent être utilisés pour créer des instances de types nommés et de types anonymes.
Déclarations
Les déclarations d’instances de types nommés et anonymes peuvent sembler presque identiques, mais leurs effets ne sont pas identiques. Chaque catégorie a des capacités et des restrictions propres. L’exemple suivant montre un moyen pratique de déclarer et d’initialiser une instance d’une classe nommée, Customer
, à l’aide d’une liste d’initialiseurs d’objets. Notez que le nom de la classe est spécifié après le mot clé New
.
Dim namedCust = New Customer With {.Name = "Terry Adams"}
Un type anonyme n’a pas de nom utilisable. Par conséquent, une instanciation d’un type anonyme ne peut pas inclure un nom de classe.
Dim anonymousCust = New With {.Name = "Hugo Garcia"}
Les exigences et les résultats des deux déclarations ne sont pas les mêmes. Pour namedCust
, une classe Customer
qui a une propriété Name
doit déjà exister et la déclaration crée une instance de cette classe. Pour anonymousCust
, le compilateur définit une nouvelle classe qui a une propriété, une chaîne appelée Name
et crée une instance de cette classe.
Types nommés
Les initialiseurs d’objets fournissent un moyen simple d’appeler le constructeur d’un type, puis de définir les valeurs d’une ou de toutes les propriétés dans une seule instruction. Le compilateur appelle le constructeur approprié pour l’instruction : le constructeur sans paramètre si aucun argument n’est présenté, ou un constructeur paramétrable si un ou plusieurs arguments sont envoyés. Après cela, les propriétés spécifiées sont initialisées dans l’ordre dans lequel elles sont présentées dans la liste d’initialiseurs.
Chaque initialisation dans la liste d’initialiseurs se compose de l’affectation d’une valeur initiale à un membre de la classe. Les noms et les types de données des membres sont déterminés lorsque la classe est définie. Dans les exemples suivants, la classe Customer
doit exister et doit avoir des membres nommés Name
et City
qui peuvent accepter des valeurs de chaîne.
Dim cust0 As Customer = New Customer With {.Name = "Toni Poe",
.City = "Louisville"}
Vous pouvez également obtenir le même résultat à l’aide du code suivant :
Dim cust1 As New Customer With {.Name = "Toni Poe",
.City = "Louisville"}
Chacune de ces déclarations équivaut à l’exemple suivant, qui crée un objet Customer
à l’aide du constructeur sans paramètre, puis spécifie les valeurs initiales des propriétés Name
et City
à l’aide d’une instruction With
.
Dim cust2 As New Customer()
With cust2
.Name = "Toni Poe"
.City = "Louisville"
End With
Si la classe Customer
contient un constructeur paramétrable qui vous permet d’envoyer une valeur pour Name
, par exemple, vous pouvez également déclarer et initialiser un objet Customer
de la manière suivante :
Dim cust3 As Customer =
New Customer("Toni Poe") With {.City = "Louisville"}
' --or--
Dim cust4 As New Customer("Toni Poe") With {.City = "Louisville"}
Vous n’avez pas besoin d’initialiser toutes les propriétés, comme le montre le code suivant.
Dim cust5 As Customer = New Customer With {.Name = "Toni Poe"}
Toutefois, la liste d’initialisation ne peut pas être vide. Les propriétés non initialisées conservent leurs valeurs par défaut.
Inférence de type avec des types nommés
Vous pouvez raccourcir le code de la déclaration de cust1
en combinant les initialiseurs d’objets et l’inférence de type local. Cela vous permet d’omettre la clause As
dans la déclaration de variable. Le type de données de la variable est déduit du type de l’objet créé par l’affectation. Dans l’exemple suivant, le type de cust6
est Customer
.
Dim cust6 = New Customer With {.Name = "Toni Poe",
.City = "Louisville"}
Remarques sur les types nommés
Un membre de classe ne peut pas être initialisé plusieurs fois dans la liste d’initialiseurs d’objets. La déclaration de
cust7
provoque une erreur.'' This code does not compile because Name is initialized twice. ' Dim cust7 = New Customer With {.Name = "Toni Poe", ' .City = "Louisville", ' .Name = "Blue Yonder Airlines"}
Un membre peut être utilisé pour initialiser lui-même ou un autre champ. Si un membre est accessible avant son initialisation, comme dans la déclaration suivante pour
cust8
, la valeur par défaut est utilisée. N’oubliez pas que lorsqu’une déclaration qui utilise un initialiseur d’objet est traitée, la première chose qui se produit est que le constructeur approprié est appelé. Après cela, les champs individuels de la liste d’initialiseurs sont initialisés. Dans les exemples suivants, la valeur par défaut deName
est affectée pourcust8
et une valeur initialisée est affectée danscust9
.Dim cust8 = New Customer With {.Name = .Name & ", President"} Dim cust9 = New Customer With {.Name = "Toni Poe", .Title = .Name & ", President"}
L’exemple suivant utilise le constructeur paramétrable de
cust3
et decust4
pour déclarer et initialisercust10
etcust11
.Dim cust10 = New Customer("Toni Poe") With {.Name = .Name & ", President"} ' --or-- Dim cust11 As New Customer("Toni Poe") With {.Name = .Name & ", President"}
Les initialiseurs d’objet peuvent être imbriqués. Dans l’exemple suivant,
AddressClass
est une classe qui a deux propriétés,City
etState
, et la classeCustomer
a une propriétéAddress
qui est une instance deAddressClass
.Dim cust12 = New Customer With {.Name = "Toni Poe", .Address = New AddressClass With {.City = "Louisville", .State = "Kentucky"}} Console.WriteLine(cust12.Address.State)
La liste d’initialisation ne peut pas être vide.
L’instance initialisée ne peut pas être de type Object.
Les membres de classe initialisés ne peuvent pas être des membres partagés, des membres en lecture seule, des constantes ou des appels de méthode.
Les membres de classe initialisés ne peuvent pas être indexés ou qualifiés. Les exemples suivants déclenchent des erreurs de compilateur :
'' Not valid.
' Dim c1 = New Customer With {.OrderNumbers(0) = 148662}
' Dim c2 = New Customer with {.Address.City = "Springfield"}
Types anonymes
Les types anonymes utilisent des initialiseurs d’objets pour créer des instances de nouveaux types que vous ne définissez pas explicitement et ne nommez pas. Au lieu de cela, le compilateur génère un type en fonction des propriétés que vous désignez dans la liste d’initialiseurs d’objets. Étant donné que le nom du type n’est pas spécifié, il est appelé type anonyme. Par exemple, comparez la déclaration suivante à la déclaration précédente pour cust6
.
Dim cust13 = New With {.Name = "Toni Poe",
.City = "Louisville"}
La seule différence est qu’aucun nom n’est spécifié après New
pour le type de données. Cependant, ce qui se passe est assez différent. Le compilateur définit un nouveau type anonyme qui a deux propriétés, Name
et City
, et crée une instance de celui-ci avec les valeurs spécifiées. L’inférence de type détermine les types de Name
et de City
dans l’exemple pour être des chaînes.
Attention
Le nom du type anonyme est généré par le compilateur et peut varier de la compilation à la compilation. Votre code ne doit pas utiliser ou s’appuyer sur le nom d’un type anonyme.
Étant donné que le nom du type n’est pas disponible, vous ne pouvez pas utiliser une clause As
pour déclarer cust13
. Son type doit être déduit. Sans utiliser la liaison tardive, cela limite l’utilisation de types anonymes aux variables locales.
Les types anonymes fournissent une prise en charge critique pour les requêtes LINQ. Pour plus d’informations sur l’utilisation de types anonymes dans les requêtes, consultez Types anonymes et Présentation de LINQ dans Visual Basic.
Remarques sur les types anonymes
En règle générale, toutes ou la plupart des propriétés d’une déclaration de type anonyme sont des propriétés clés, qui sont indiquées en tapant le mot clé
Key
devant le nom de la propriété.Dim anonymousCust1 = New With {Key .Name = "Hugo Garcia", Key .City = "Louisville"}
Pour plus d’informations sur les propriétés de clé, consultez Clé .
Comme les types nommés, les listes d’initialiseurs pour les définitions de types anonymes doivent déclarer au moins une propriété.
Dim anonymousCust = New With {.Name = "Hugo Garcia"}
Lorsqu’une instance d’un type anonyme est déclarée, le compilateur génère une définition de type anonyme correspondante. Les noms et les types de données des propriétés sont extraits de la déclaration d’instance et sont inclus par le compilateur dans la définition. Les propriétés ne sont pas nommées et définies à l’avance, car elles concernent un type nommé. Leurs types sont déduits. Vous ne pouvez pas spécifier les types de données des propriétés à l’aide d’une clause
As
.Les types anonymes peuvent également établir les noms et les valeurs de leurs propriétés de plusieurs autres façons. Par exemple, une propriété de type anonyme peut prendre le nom et la valeur d’une variable, ou le nom et la valeur d’une propriété d’un autre objet.
' 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}
Pour plus d’informations sur les options de définition des propriétés dans les types anonymes, consultez Guide pratique pour déduire les noms et les types de propriétés dans les déclarations de types anonymes.