about_Classes_Constructors
Description courte
Décrit comment définir des constructeurs pour les classes PowerShell.
Description longue
Les constructeurs vous permettent de définir des valeurs par défaut et de valider la logique d’objet au moment de la création de l’instance de la classe. Les constructeurs ont le même nom que la classe. Les constructeurs peuvent avoir des paramètres pour initialiser les membres de données du nouvel objet.
Les constructeurs de classe PowerShell sont définis en tant que méthodes spéciales sur la classe. Ils se comportent de la même façon que les méthodes de classe PowerShell avec les exceptions suivantes :
- Les constructeurs n’ont pas de type de sortie. Ils ne peuvent pas utiliser le
return
mot clé. - Les constructeurs ont toujours le même nom que la classe.
- Les constructeurs ne peuvent pas être appelés directement. Ils s’exécutent uniquement lorsqu’une instance est créée.
- Les constructeurs n’apparaissent jamais dans la sortie de l’applet de
Get-Member
commande.
Pour plus d’informations sur les méthodes de classe PowerShell, consultez about_Classes_Methods.
La classe peut avoir zéro ou plusieurs constructeurs définis. Si aucun constructeur n’est défini, la classe reçoit un constructeur sans paramètre par défaut. Ce constructeur initialise tous les membres à leurs valeurs par défaut. Les types d’objets et les chaînes reçoivent des valeurs Null. Lorsque vous définissez le constructeur, aucun constructeur sans paramètre par défaut n’est créé. Créez un constructeur sans paramètre si nécessaire.
Vous pouvez également définir un constructeur statique sans paramètre.
Syntaxe
Les constructeurs de classes utilisent les syntaxes suivantes :
Syntaxe du constructeur par défaut
<class-name> () [: base([<params>])] {
<body>
}
Syntaxe du constructeur statique
static <class-name> () [: base([<params>])] {
<body>
}
Syntaxe de constructeur paramétrable (une ligne)
<class-name> ([[<parameter-type>]$<parameter-name>[, [<parameter-type>]$<parameter-name>...]]) [: base([<params>])] {
<body>
}
Syntaxe de constructeur paramétrable (multiligne)
<class-name> (
[<parameter-type>]$<parameter-name>[,
[<parameter-type>]$<parameter-name>...]
) [: base([<params>])] {
<body>
}
Exemples
Exemple 1 : Définition d’une classe avec le constructeur par défaut
La classe ExampleBook1 ne définit pas de constructeur. Au lieu de cela, il utilise le constructeur automatique par défaut.
class ExampleBook1 {
[string] $Name
[string] $Author
[int] $Pages
[datetime] $PublishedOn
}
[ExampleBook1]::new()
Name Author Pages PublishedOn
---- ------ ----- -----------
0 1/1/0001 12:00:00 AM
Remarque
La valeur par défaut des propriétés Name et Author est $null
due au fait qu’elles sont typées sous forme de chaînes, qui est un type de référence. Les autres propriétés ont la valeur par défaut pour leur type défini, car elles sont des propriétés de type valeur. Pour plus d’informations sur les valeurs par défaut des propriétés, consultez « Valeurs de propriété par défaut » dans about_Classes_Properties.
Exemple 2 : substitution du constructeur par défaut
ExampleBook2 définit explicitement le constructeur par défaut, en définissant les valeurs de PublishedOn sur la date actuelle et les pages 1
sur .
class ExampleBook2 {
[string] $Name
[string] $Author
[int] $Pages
[datetime] $PublishedOn
ExampleBook2() {
$this.PublishedOn = (Get-Date).Date
$this.Pages = 1
}
}
[ExampleBook2]::new()
Name Author Pages PublishedOn
---- ------ ----- -----------
1 11/1/2023 12:00:00 AM
Exemple 3 : Définition des surcharges de constructeur
La classe ExampleBook3 définit trois surcharges de constructeur, ce qui permet aux utilisateurs de créer une instance de la classe à partir d’une table de hachage, en passant chaque valeur de propriété et en passant le nom du livre et de l’auteur. La classe ne définit pas le constructeur par défaut.
class ExampleBook3 {
[string] $Name
[string] $Author
[int] $Pages
[datetime] $PublishedOn
ExampleBook3([hashtable]$Info) {
switch ($Info.Keys) {
'Name' { $this.Name = $Info.Name }
'Author' { $this.Author = $Info.Author }
'Pages' { $this.Pages = $Info.Pages }
'PublishedOn' { $this.PublishedOn = $Info.PublishedOn }
}
}
ExampleBook3(
[string] $Name,
[string] $Author,
[int] $Pages,
[datetime] $PublishedOn
) {
$this.Name = $Name
$this.Author = $Author
$this.Pages = $Pages
$this.PublishedOn = $PublishedOn
}
ExampleBook3([string]$Name, [string]$Author) {
$this.Name = $Name
$this.Author = $Author
}
}
[ExampleBook3]::new(@{
Name = 'The Hobbit'
Author = 'J.R.R. Tolkien'
Pages = 310
PublishedOn = '1937-09-21'
})
[ExampleBook3]::new('The Hobbit', 'J.R.R. Tolkien', 310, '1937-09-21')
[ExampleBook3]::new('The Hobbit', 'J.R.R. Tolkien')
[ExampleBook3]::new()
Name Author Pages PublishedOn
---- ------ ----- -----------
The Hobbit J.R.R. Tolkien 310 9/21/1937 12:00:00 AM
The Hobbit J.R.R. Tolkien 310 9/21/1937 12:00:00 AM
The Hobbit J.R.R. Tolkien 0 1/1/0001 12:00:00 AM
MethodException:
Line |
42 | [ExampleBook3]::new()
| ~~~~~~~~~~~~~~~~~~~~~
| Cannot find an overload for "new" and the argument count: "0".
L’appel du constructeur par défaut retourne une exception de méthode. Le constructeur automatique par défaut est défini uniquement pour une classe lorsque la classe ne définit aucun constructeur. Étant donné que ExampleBook3 définit plusieurs surcharges, le constructeur par défaut n’est pas automatiquement ajouté à la classe.
Exemple 4 - Chaînage de constructeurs avec une méthode partagée
Cet exemple montre comment écrire du code partagé réutilisable pour les constructeurs.
Les classes PowerShell ne peuvent pas utiliser le chaînage de constructeurs. Par conséquent, cet exemple de classe définit une Init()
méthode à la place. La méthode a plusieurs surcharges. Les surcharges avec moins de paramètres appellent les surcharges plus explicites avec des valeurs par défaut pour les paramètres non spécifiés.
class ExampleBook4 {
[string] $Name
[string] $Author
[datetime] $PublishedOn
[int] $Pages
ExampleBook4() {
$this.Init()
}
ExampleBook4([string]$Name) {
$this.Init($Name)
}
ExampleBook4([string]$Name, [string]$Author) {
$this.Init($Name, $Author)
}
ExampleBook4([string]$Name, [string]$Author, [datetime]$PublishedOn) {
$this.Init($Name, $Author, $PublishedOn)
}
ExampleBook4(
[string]$Name,
[string]$Author,
[datetime]$PublishedOn,
[int]$Pages
) {
$this.Init($Name, $Author, $PublishedOn, $Pages)
}
hidden Init() {
$this.Init('Unknown')
}
hidden Init([string]$Name) {
$this.Init($Name, 'Unknown')
}
hidden Init([string]$Name, [string]$Author) {
$this.Init($Name, $Author, (Get-Date).Date)
}
hidden Init([string]$Name, [string]$Author, [datetime]$PublishedOn) {
$this.Init($Name, $Author, $PublishedOn, 1)
}
hidden Init(
[string]$Name,
[string]$Author,
[datetime]$PublishedOn,
[int]$Pages
) {
$this.Name = $Name
$this.Author = $Author
$this.PublishedOn = $PublishedOn
$this.Pages = $Pages
}
}
[ExampleBook4]::new()
[ExampleBook4]::new('The Hobbit')
[ExampleBook4]::new('The Hobbit', 'J.R.R. Tolkien')
[ExampleBook4]::new('The Hobbit', 'J.R.R. Tolkien', (Get-Date '1937-9-21'))
[ExampleBook4]::new(
'The Hobbit',
'J.R.R. Tolkien',
(Get-Date '1937-9-21'),
310
)
Name Author PublishedOn Pages
---- ------ ----------- -----
Unknown Unknown 11/1/2023 12:00:00 AM 1
The Hobbit Unknown 11/1/2023 12:00:00 AM 1
The Hobbit J.R.R. Tolkien 11/1/2023 12:00:00 AM 1
The Hobbit J.R.R. Tolkien 9/21/1937 12:00:00 AM 1
The Hobbit J.R.R. Tolkien 9/21/1937 12:00:00 AM 310
Exemple 5 : constructeurs de classes dérivées
Les exemples suivants utilisent des classes qui définissent les constructeurs statiques, par défaut et paramétrables pour une classe de base et une classe dérivée qui hérite de la classe de base.
class BaseExample {
static [void] DefaultMessage([type]$Type) {
Write-Verbose "[$($Type.Name)] default constructor"
}
static [void] StaticMessage([type]$Type) {
Write-Verbose "[$($Type.Name)] static constructor"
}
static [void] ParamMessage([type]$Type, [object]$Value) {
Write-Verbose "[$($Type.Name)] param constructor ($Value)"
}
static BaseExample() { [BaseExample]::StaticMessage([BaseExample]) }
BaseExample() { [BaseExample]::DefaultMessage([BaseExample]) }
BaseExample($Value) { [BaseExample]::ParamMessage([BaseExample], $Value) }
}
class DerivedExample : BaseExample {
static DerivedExample() { [BaseExample]::StaticMessage([DerivedExample]) }
DerivedExample() { [BaseExample]::DefaultMessage([DerivedExample]) }
DerivedExample([int]$Number) : base($Number) {
[BaseExample]::ParamMessage([DerivedExample], $Number)
}
DerivedExample([string]$String) {
[BaseExample]::ParamMessage([DerivedExample], $String)
}
}
Le bloc suivant montre la messagerie détaillée permettant d’appeler les constructeurs de classe de base. Le message du constructeur statique n’est émis que la première fois qu’une instance de la classe est créée.
PS> $VerbosePreference = 'Continue'
PS> $b = [BaseExample]::new()
VERBOSE: [BaseExample] static constructor
VERBOSE: [BaseExample] default constructor
PS> $b = [BaseExample]::new()
VERBOSE: [BaseExample] default constructor
PS> $b = [BaseExample]::new(1)
VERBOSE: [BaseExample] param constructor (1)
Le bloc suivant affiche la messagerie détaillée permettant d’appeler les constructeurs de classes dérivées dans une nouvelle session. La première fois qu’un constructeur de classe dérivée est appelé, les constructeurs statiques pour la classe de base et la classe dérivée sont appelés. Ces constructeurs ne sont pas appelés à nouveau dans la session. Les constructeurs de la classe de base s’exécutent toujours avant les constructeurs de la classe dérivée.
PS> $VerbosePreference = 'Continue'
PS> $c = [DerivedExample]::new()
VERBOSE: [BaseExample] static constructor
VERBOSE: [DerivedExample] static constructor
VERBOSE: [BaseExample] default constructor
VERBOSE: [DerivedExample] default constructor
PS> $c = [DerivedExample]::new()
VERBOSE: [BaseExample] default constructor
VERBOSE: [DerivedExample] default constructor
PS> $c = [DerivedExample]::new(1)
VERBOSE: [BaseExample] param constructor (1)
VERBOSE: [DerivedExample] param constructor (1)
PS> $c = [DerivedExample]::new('foo')
VERBOSE: [BaseExample] default constructor
VERBOSE: [DerivedExample] param constructor (foo)
Ordre d’exécution du constructeur
Lorsqu’une classe instancie, le code d’un ou plusieurs constructeurs s’exécute.
Pour les classes qui n’héritent pas d’une autre classe, l’ordre est :
- Constructeur statique pour la classe.
- Surcharge de constructeur applicable pour la classe.
Pour les classes dérivées qui héritent d’une autre classe, l’ordre est :
- Constructeur statique pour la classe de base.
- Constructeur statique pour la classe dérivée.
- Si le constructeur de classe dérivée appelle explicitement une surcharge de constructeur de base, il exécute ce constructeur pour la classe de base. S’il n’appelle pas explicitement un constructeur de base, il exécute le constructeur par défaut pour la classe de base.
- Surcharge de constructeur applicable pour la classe dérivée.
Dans tous les cas, les constructeurs statiques ne s’exécutent qu’une seule fois dans une session.
Pour obtenir un exemple de comportement et d’ordre du constructeur, consultez l’exemple 5.
Constructeurs masqués
Vous pouvez masquer les constructeurs d’une classe en les déclarant avec le hidden
mot clé. Les constructeurs de classes masquées sont les suivants :
- Non inclus dans la sortie par défaut de la classe.
- Non inclus dans la liste des membres de classe retournés par l’applet de
Get-Member
commande. Pour afficher les propriétés masquées avecGet-Member
, utilisez le paramètre Force . - Non affiché dans la saisie semi-automatique de tabulation ou IntelliSense, sauf si la saisie semi-automatique se produit dans la classe qui définit la propriété masquée.
- Membres publics de la classe. Ils sont accessibles et modifiés. Masquage d’une propriété ne le rend pas privé. Elle masque uniquement la propriété comme décrit dans les points précédents.
Remarque
Lorsque vous masquez un constructeur, l’option new()
est supprimée d’IntelliSense et des résultats de saisie semi-automatique.
Pour plus d’informations sur la hidden
mot clé, consultez about_Hidden.
Constructeurs statiques
Vous pouvez définir un constructeur comme appartenant à la classe elle-même au lieu d’instances de la classe en déclarant le constructeur avec le static
mot clé.
Constructeurs de classe statique :
- Appelez uniquement la première fois qu’une instance de la classe est créée dans la session.
- Impossible d’avoir de paramètres.
- Impossible d’accéder aux propriétés ou méthodes d’instance avec la
$this
variable.
Constructeurs pour les classes dérivées
Lorsqu’une classe hérite d’une autre classe, les constructeurs peuvent appeler un constructeur de la classe de base avec le base
mot clé. Si la classe dérivée n’appelle pas explicitement un constructeur de la classe de base, elle appelle le constructeur par défaut pour la classe de base à la place.
Pour appeler un constructeur de base nondefault, ajoutez : base(<parameters>)
après les paramètres du constructeur et avant le bloc de corps.
class <derived-class> : <base-class> {
<derived-class>(<derived-parameters>) : <base-class>(<base-parameters>) {
# initialization code
}
}
Lors de la définition d’un constructeur qui appelle un constructeur de classe de base, les paramètres peuvent être l’un des éléments suivants :
- Variable de n’importe quel paramètre sur le constructeur de classe dérivé.
- Toute valeur statique.
- Toute expression qui prend la valeur d’une valeur du type de paramètre.
Pour obtenir un exemple de constructeur sur une classe dérivée, consultez l’exemple 5.
Constructeurs chaînants
Contrairement à C#, les constructeurs de classes PowerShell ne peuvent pas utiliser le chaînage avec la : this(<parameters>)
syntaxe. Pour réduire la duplication de code, utilisez une méthode masquée Init()
avec plusieurs surcharges dans le même effet. L’exemple 4 montre une classe à l’aide de ce modèle.
Ajout de propriétés et de méthodes d’instance avec Update-TypeData
Au-delà de déclarer des propriétés et des méthodes directement dans la définition de classe, vous pouvez définir des propriétés pour les instances d’une classe dans le constructeur statique à l’aide de l’applet Update-TypeData
de commande.
Utilisez cet extrait de code comme point de départ pour le modèle. Remplacez le texte de l’espace réservé entre crochets angle en fonction des besoins.
class <class-name> {
static [hashtable[]] $MemberDefinitions = @(
@{
Name = '<member-name>'
MemberType = '<member-type>'
Value = <member-definition>
}
)
static <class-name>() {
$TypeName = [<class-name>].Name
foreach ($Definition in [<class-name>]::MemberDefinitions) {
Update-TypeData -TypeName $TypeName @Definition
}
}
}
Conseil
L’applet Add-Member
de commande peut ajouter des propriétés et des méthodes à une classe dans des constructeurs non statiques, mais l’applet de commande est exécutée chaque fois que le constructeur est appelé. L’utilisation Update-TypeData
dans le constructeur statique garantit que le code permettant d’ajouter les membres à la classe ne doit s’exécuter qu’une seule fois dans une session.
Ajoutez uniquement des propriétés à la classe dans des constructeurs non statiques lorsqu’elles ne peuvent pas être définies avec Update-TypeData
, comme les propriétés en lecture seule.
Pour plus d’informations sur la définition des méthodes d’instance avec Update-TypeData
, consultez about_Classes_Methods. Pour plus d’informations sur la définition des propriétés d’instance avec Update-TypeData
, consultez about_Classes_Properties.
Limites
Les constructeurs de classes PowerShell présentent les limitations suivantes :
Le chaînage du constructeur n’est pas implémenté.
Solution de contournement : définissez des méthodes masquées
Init()
et appelez-les à partir des constructeurs.Les paramètres du constructeur ne peuvent pas utiliser d’attributs, y compris les attributs de validation.
Solution de contournement : réaffectez les paramètres dans le corps du constructeur avec l’attribut de validation.
Les paramètres du constructeur ne peuvent pas définir de valeurs par défaut. Les paramètres sont toujours obligatoires.
Solution de contournement : aucune.
Si une surcharge d’un constructeur est masquée, chaque surcharge du constructeur est traitée comme masquée également.
Solution de contournement : aucune.
Voir aussi
Commentaires
https://aka.ms/ContentUserFeedback.
Bientôt disponible : Tout au long de 2024, nous allons supprimer progressivement GitHub Issues comme mécanisme de commentaires pour le contenu et le remplacer par un nouveau système de commentaires. Pour plus d’informations, consultezEnvoyer et afficher des commentaires pour