Partager via


about_Classes_Methods

Description courte

Décrit comment définir des méthodes pour les classes PowerShell.

Description longue

Les méthodes définissent les actions qu’une classe peut effectuer. Les méthodes peuvent prendre des paramètres qui spécifient des données d’entrée. Les méthodes définissent toujours un type de sortie. Si une méthode ne retourne aucune sortie, elle doit avoir le type de sortie Void . Si une méthode ne définit pas explicitement un type de sortie, le type de sortie de la méthode est Void.

Dans les méthodes de classe, aucun objet n’est envoyé au pipeline, sauf ceux spécifiés dans l’instruction return . Il n’existe aucune sortie accidentelle vers le pipeline à partir du code.

Remarque

Cela diffère fondamentalement de la façon dont les fonctions PowerShell gèrent la sortie, où tout va au pipeline.

Les erreurs non déterminables écrites dans le flux d’erreurs à partir d’une méthode de classe ne sont pas transmises. Vous devez utiliser throw pour afficher une erreur de fin. À l’aide Write-* des applets de commande, vous pouvez toujours écrire dans les flux de sortie de PowerShell à partir d’une méthode de classe. Les applets de commande respectent les variables de préférence dans l’étendue appelante. Toutefois, vous devez éviter d’utiliser les Write-* applets de commande afin que la méthode génère uniquement des objets à l’aide de l’instruction return .

Les méthodes de classe peuvent référencer l’instance actuelle de l’objet de classe à l’aide de la $this variable automatique pour accéder aux propriétés et à d’autres méthodes définies dans la classe actuelle. La $this variable automatique n’est pas disponible dans les méthodes statiques.

Les méthodes de classe peuvent avoir n’importe quel nombre d’attributs, y compris les attributs masqués et statiques .

Syntaxe

Les méthodes de classe utilisent les syntaxes suivantes :

Syntaxe d’une ligne

[[<attribute>]...] [hidden] [static] [<output-type>] <method-name> ([<method-parameters>]) { <body> }

Syntaxe multiligne

[[<attribute>]...]
[hidden]
[static]
[<output-type>] <method-name> ([<method-parameters>]) {
  <body>
}

Exemples

Exemple 1 - Définition de méthode minimale

La GetVolume() méthode de la classe ExampleCube1 retourne le volume du cube. Il définit le type de sortie en tant que nombre flottant et retourne le résultat de la multiplication des propriétés Height, Length et Width de l’instance.

class ExampleCube1 {
    [float]   $Height
    [float]   $Length
    [float]   $Width

    [float] GetVolume() { return $this.Height * $this.Length * $this.Width }
}

$box = [ExampleCube1]@{
    Height = 2
    Length = 2
    Width  = 3
}

$box.GetVolume()
12

Exemple 2 - Méthode avec des paramètres

La GeWeight() méthode prend une entrée de nombre flottant pour la densité du cube et retourne le poids du cube, calculé en tant que volume multiplié par densité.

class ExampleCube2 {
    [float]   $Height
    [float]   $Length
    [float]   $Width

    [float] GetVolume() { return $this.Height * $this.Length * $this.Width }
    [float] GetWeight([float]$Density) {
        return $this.GetVolume() * $Density
    }
}

$cube = [ExampleCube2]@{
    Height = 2
    Length = 2
    Width  = 3
}

$cube.GetWeight(2.5)
30

Exemple 3 - Méthode sans sortie

Cet exemple définit la Validate() méthode avec le type de sortie en tant que System.Void. Cette méthode ne retourne aucune sortie. Au lieu de cela, si la validation échoue, elle génère une erreur. La GetVolume() méthode appelle Validate() avant de calculer le volume du cube. En cas d’échec de la validation, la méthode se termine avant le calcul.

class ExampleCube3 {
    [float]   $Height
    [float]   $Length
    [float]   $Width

    [float] GetVolume() {
        $this.Validate()

        return $this.Height * $this.Length * $this.Width
    }

    [void] Validate() {
        $InvalidProperties = @()
        foreach ($Property in @('Height', 'Length', 'Width')) {
            if ($this.$Property -le 0) {
                $InvalidProperties += $Property
            }
        }

        if ($InvalidProperties.Count -gt 0) {
            $Message = @(
                'Invalid cube properties'
                "('$($InvalidProperties -join "', '")'):"
                "Cube dimensions must all be positive numbers."
            ) -join ' '
            throw $Message
        }
    }
}

$Cube = [ExampleCube3]@{ Length = 1 ; Width = -1 }
$Cube

$Cube.GetVolume()
Height Length Width
------ ------ -----
  0.00   1.00 -1.00

Exception:
Line |
  20 |              throw $Message
     |              ~~~~~~~~~~~~~~
     | Invalid cube properties ('Height', 'Width'): Cube dimensions must
     | all be positive numbers.

La méthode lève une exception, car les propriétés Height et Width ne sont pas valides, ce qui empêche la classe de calculer le volume actuel.

Exemple 4 - Méthode statique avec surcharges

La classe ExampleCube4 définit la méthode GetVolume() statique avec deux surcharges. La première surcharge a des paramètres pour les dimensions du cube et un indicateur pour indiquer si la méthode doit valider l’entrée.

La deuxième surcharge inclut uniquement les entrées numériques. Il appelle la première surcharge avec $Static as $true. La deuxième surcharge permet aux utilisateurs d’appeler la méthode sans toujours avoir à définir s’il faut valider strictement l’entrée.

La classe définit GetVolume() également comme méthode d’instance (non statique). Cette méthode appelle la deuxième surcharge statique, ce qui garantit que la méthode d’instance GetVolume() valide toujours les dimensions du cube avant de retourner la valeur de sortie.

class ExampleCube4 {
    [float]   $Height
    [float]   $Length
    [float]   $Width

    static [float] GetVolume(
        [float]$Height,
        [float]$Length,
        [float]$Width,
        [boolean]$Strict
    ) {
        $Signature = "[ExampleCube4]::GetVolume({0}, {1}, {2}, {3})"
        $Signature = $Signature -f $Height, $Length, $Width, $Strict
        Write-Verbose "Called $Signature"

        if ($Strict) {
            [ValidateScript({$_ -gt 0 })]$Height = $Height
            [ValidateScript({$_ -gt 0 })]$Length = $Length
            [ValidateScript({$_ -gt 0 })]$Width  = $Width
        }

        return $Height * $Length * $Width
    }

    static [float] GetVolume([float]$Height, [float]$Length, [float]$Width) {
        $Signature = "[ExampleCube4]::GetVolume($Height, $Length, $Width)"
        Write-Verbose "Called $Signature"

        return [ExampleCube4]::GetVolume($Height, $Length, $Width, $true)
    }

    [float] GetVolume() {
        Write-Verbose "Called `$this.GetVolume()"
        return [ExampleCube4]::GetVolume(
            $this.Height,
            $this.Length,
            $this.Width
        )
    }
}

$VerbosePreference = 'Continue'
$Cube = [ExampleCube4]@{ Height = 2 ; Length = 2 }
$Cube.GetVolume()
VERBOSE: Called $this.GetVolume()
VERBOSE: Called [ExampleCube4]::GetVolume(2, 2, 0)
VERBOSE: Called [ExampleCube4]::GetVolume(2, 2, 0, True)

MetadataError:
Line |
  19 |              [ValidateScript({$_ -gt 0 })]$Width  = $Width
     |              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | The variable cannot be validated because the value 0 is not a valid
     | value for the Width variable.

Les messages détaillés dans les définitions de méthode montrent comment l’appel initial pour $this.GetVolume() appeler la méthode statique.

Appel de la méthode statique directement avec le paramètre Strict comme $false retour 0 pour le volume.

[ExampleCube4]::GetVolume($Cube.Height, $Cube.Length, $Cube.Width, $false)
VERBOSE: Called [ExampleCube4]::GetVolume(2, 2, 0, False)
0

Signatures et surcharges de méthode

Chaque méthode de classe a une signature unique qui définit comment appeler la méthode. Le type de sortie, le nom et les paramètres de la méthode définissent la signature de la méthode.

Lorsqu’une classe définit plusieurs méthodes portant le même nom, les définitions de cette méthode sont des surcharges. Les surcharges d’une méthode doivent avoir des paramètres différents. Une méthode ne peut pas définir deux implémentations avec les mêmes paramètres, même si les types de sortie sont différents.

La classe suivante définit deux méthodes et Shuffle() Deal(). La Deal() méthode définit deux surcharges, une sans aucun paramètre et l’autre avec le paramètre Count .

class CardDeck {
    [string[]]$Cards  = @()
    hidden [string[]]$Dealt  = @()
    hidden [string[]]$Suits  = @('Clubs', 'Diamonds', 'Hearts', 'Spades')
    hidden [string[]]$Values = 2..10 + @('Jack', 'Queen', 'King', 'Ace')

    CardDeck() {
        foreach($Suit in $this.Suits) {
            foreach($Value in $this.Values) {
                $this.Cards += "$Value of $Suit"
            }
        }
        $this.Shuffle()
    }

    [void] Shuffle() {
        $this.Cards = $this.Cards + $this.Dealt | Where-Object -FilterScript {
             -not [string]::IsNullOrEmpty($_)
        } | Get-Random -Count $this.Cards.Count
    }

    [string] Deal() {
        if ($this.Cards.Count -eq 0) { throw "There are no cards left." }

        $Card        = $this.Cards[0]
        $this.Cards  = $this.Cards[1..$this.Cards.Count]
        $this.Dealt += $Card

        return $Card
    }

    [string[]] Deal([int]$Count) {
        if ($Count -gt $this.Cards.Count) {
            throw "There are only $($this.Cards.Count) cards left."
        } elseif ($Count -lt 1) {
            throw "You must deal at least 1 card."
        }

        return (1..$Count | ForEach-Object { $this.Deal() })
    }
}

Sortie de la méthode

Par défaut, les méthodes n’ont aucune sortie. Si une signature de méthode inclut un type de sortie explicite autre que Void, la méthode doit retourner un objet de ce type. Les méthodes n’émettent aucune sortie, sauf lorsque le return mot clé retourne explicitement un objet.

Paramètres de la méthode

Les méthodes de classe peuvent définir des paramètres d’entrée à utiliser dans le corps de la méthode. Les paramètres de méthode sont placés entre parenthèses et séparés par des virgules. Des parenthèses vides indiquent que la méthode ne requiert aucun paramètre.

Les paramètres peuvent être définis sur une seule ligne ou plusieurs lignes. Les blocs suivants montrent la syntaxe des paramètres de méthode.

([[<parameter-type>]]$<parameter-name>[, [[<parameter-type>]]$<parameter-name>])
(
    [[<parameter-type>]]$<parameter-name>[,
    [[<parameter-type>]]$<parameter-name>]
)

Les paramètres de méthode peuvent être fortement typés. Si un paramètre n’est pas tapé, la méthode accepte n’importe quel objet pour ce paramètre. Si le paramètre est typé, la méthode tente de convertir la valeur de ce paramètre en type correct, ce qui lève une exception si l’entrée ne peut pas être convertie.

Les paramètres de méthode ne peuvent pas définir de valeurs par défaut. Tous les paramètres de méthode sont obligatoires.

Les paramètres de méthode ne peuvent pas avoir d’autres attributs. Cela empêche les méthodes d’utiliser des paramètres avec les Validate* attributs. Pour plus d’informations sur les attributs de validation, consultez about_Functions_Advanced_Parameters.

Vous pouvez utiliser l’un des modèles suivants pour ajouter la validation aux paramètres de méthode :

  1. Réaffectez les paramètres aux mêmes variables avec les attributs de validation requis. Cela fonctionne pour les méthodes statiques et d’instance. Pour obtenir un exemple de ce modèle, consultez l’exemple 4.
  2. Permet Update-TypeData de définir un ScriptMethod attribut de validation sur les paramètres directement. Cela fonctionne uniquement pour les méthodes d’instance. Pour plus d’informations, consultez la section Définition des méthodes d’instance avec update-TypeData .

Variables automatiques dans les méthodes

Toutes les variables automatiques ne sont pas disponibles dans les méthodes. La liste suivante inclut des variables automatiques et des suggestions pour savoir si et comment les utiliser dans les méthodes de classe PowerShell. Les variables automatiques non incluses dans la liste ne sont pas disponibles pour les méthodes de classe.

  • $? - Accès comme normal.
  • $_ - Accès comme normal.
  • $args - Utilisez plutôt les variables de paramètre explicites.
  • $ConsoleFileName - Accédez à la $Script:ConsoleFileName place.
  • $Error - Accès comme normal.
  • $EnabledExperimentalFeatures - Accédez à la $Script:EnabledExperimentalFeatures place.
  • $Event - Accès comme normal.
  • $EventArgs - Accès comme normal.
  • $EventSubscriber - Accès comme normal.
  • $ExecutionContext - Accédez à la $Script:ExecutionContext place.
  • $false - Accès comme normal.
  • $foreach - Accès comme normal.
  • $HOME - Accédez à la $Script:HOME place.
  • $Host - Accédez à la $Script:Host place.
  • $input - Utilisez plutôt les variables de paramètre explicites.
  • $IsCoreCLR - Accédez à la $Script:IsCoreCLR place.
  • $IsLinux - Accédez à la $Script:IsLinux place.
  • $IsMacOS - Accédez à la $Script:IsMacOS place.
  • $IsWindows - Accédez à la $Script:IsWindows place.
  • $LASTEXITCODE - Accès comme normal.
  • $Matches - Accès comme normal.
  • $MyInvocation - Accès comme normal.
  • $NestedPromptLevel - Accès comme normal.
  • $null - Accès comme normal.
  • $PID - Accédez à la $Script:PID place.
  • $PROFILE - Accédez à la $Script:PROFILE place.
  • $PSBoundParameters - N’utilisez pas cette variable. Elle est destinée aux applets de commande et aux fonctions. L’utilisation de celui-ci dans une classe peut avoir des effets secondaires inattendus.
  • $PSCmdlet - N’utilisez pas cette variable. Elle est destinée aux applets de commande et aux fonctions. L’utilisation de celui-ci dans une classe peut avoir des effets secondaires inattendus.
  • $PSCommandPath - Accès comme normal.
  • $PSCulture - Accédez à la $Script:PSCulture place.
  • $PSEdition - Accédez à la $Script:PSEdition place.
  • $PSHOME - Accédez à la $Script:PSHOME place.
  • $PSItem - Accès comme normal.
  • $PSScriptRoot - Accès comme normal.
  • $PSSenderInfo - Accédez à la $Script:PSSenderInfo place.
  • $PSUICulture - Accédez à la $Script:PSUICulture place.
  • $PSVersionTable - Accédez à la $Script:PSVersionTable place.
  • $PWD - Accès comme normal.
  • $Sender - Accès comme normal.
  • $ShellId - Accédez à la $Script:ShellId place.
  • $StackTrace - Accès comme normal.
  • $switch - Accès comme normal.
  • $this - Accès comme normal. Dans une méthode de classe, $this est toujours l’instance actuelle de la classe. Vous pouvez accéder aux propriétés et méthodes de classe avec celle-ci. Elle n’est pas disponible dans les méthodes statiques.
  • $true - Accès comme normal.

Pour plus d’informations sur les variables automatiques, consultez about_Automatic_Variables.

Méthodes masquées

Vous pouvez masquer les méthodes d’une classe en les déclarant avec le hidden mot clé. Les méthodes de classe masquées sont les suivantes :

  • Non inclus dans la liste des membres de classe retournés par l’applet de Get-Member commande. Pour afficher les méthodes masquées avec Get-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 méthode masquée.
  • Membres publics de la classe. Ils peuvent être appelés et hérités. Le masquage d’une méthode ne le rend pas privé. Elle masque uniquement la méthode comme décrit dans les points précédents.

Remarque

Lorsque vous masquez une surcharge pour une méthode, cette méthode est supprimée d’IntelliSense, des résultats d’achèvement et de la sortie par défaut pour Get-Member.

Pour plus d’informations sur le hidden mot clé, consultez about_Hidden.

Méthodes statiques

Vous pouvez définir une méthode comme appartenant à la classe elle-même au lieu d’instances de la classe en déclarant la méthode avec le static mot clé. Méthodes de classe statique :

  • Sont toujours disponibles, indépendamment de l’instanciation de classe.
  • Sont partagés entre toutes les instances de la classe.
  • Sont toujours disponibles.
  • Impossible d’accéder aux propriétés d’instance de la classe. Ils peuvent uniquement accéder aux propriétés statiques.
  • Live pour l’ensemble de la session.

Méthodes de classe dérivées

Lorsqu’une classe dérive d’une classe de base, elle hérite des méthodes de la classe de base et de leurs surcharges. Toutes les surcharges de méthode définies sur la classe de base, y compris les méthodes masquées, sont disponibles sur la classe dérivée.

Une classe dérivée peut remplacer une surcharge de méthode héritée en la redéfinissant dans la définition de classe. Pour remplacer la surcharge, les types de paramètres doivent être identiques à ceux de la classe de base. Le type de sortie de la surcharge peut être différent.

Contrairement aux constructeurs, les méthodes ne peuvent pas utiliser la : base(<parameters>) syntaxe pour appeler une surcharge de classe de base pour la méthode. La surcharge redéfinie sur la classe dérivée remplace complètement la surcharge définie par la classe de base.

L’exemple suivant montre le comportement des méthodes statiques et d’instance sur les classes dérivées.

La classe de base définit :

  • Méthodes Now() statiques pour retourner l’heure actuelle et DaysAgo() pour retourner une date dans le passé.
  • Propriété d’instance TimeStamp et méthode d’instance ToString() qui retourne la représentation sous forme de chaîne de cette propriété. Cela garantit que lorsqu’une instance est utilisée dans une chaîne, elle se convertit en chaîne datetime au lieu du nom de classe.
  • Méthode d’instance SetTimeStamp() avec deux surcharges. Lorsque la méthode est appelée sans paramètres, elle définit TimeStamp sur l’heure actuelle. Lorsque la méthode est appelée avec un DateTime, elle définit l’horodatage sur cette valeur.
class BaseClass {
    static [datetime] Now() {
        return Get-Date
    }
    static [datetime] DaysAgo([int]$Count) {
        return [BaseClass]::Now().AddDays(-$Count)
    }

    [datetime] $TimeStamp = [BaseClass]::Now()

    [string] ToString() {
        return $this.TimeStamp.ToString()
    }

    [void] SetTimeStamp([datetime]$TimeStamp) {
        $this.TimeStamp = $TimeStamp
    }
    [void] SetTimeStamp() {
        $this.TimeStamp = [BaseClass]::Now()
    }
}

Le bloc suivant définit les classes dérivées de BaseClass :

  • DerivedClassA hérite de BaseClass sans remplacement.
  • DerivedClassB remplace la DaysAgo() méthode statique pour retourner une représentation sous forme de chaîne au lieu de l’objet DateTime . Il remplace également la ToString() méthode d’instance pour renvoyer l’horodatage en tant que chaîne de date ISO8601.
  • DerivedClassC remplace la surcharge sans paramètre de la SetTimeStamp() méthode afin que la définition de l’horodatage sans paramètres définisse la date sur 10 jours avant la date actuelle.
class DerivedClassA : BaseClass     {}
class DerivedClassB : BaseClass     {
    static [string] DaysAgo([int]$Count) {
        return [BaseClass]::DaysAgo($Count).ToString('yyyy-MM-dd')
    }
    [string] ToString() {
        return $this.TimeStamp.ToString('yyyy-MM-dd')
    }
}
class DerivedClassC : BaseClass {
    [void] SetTimeStamp() {
        $this.SetTimeStamp([BaseClass]::Now().AddDays(-10))
    }
}

Le bloc suivant montre la sortie de la méthode statique Now() pour les classes définies. La sortie est la même pour chaque classe, car les classes dérivées ne remplacent pas l’implémentation de classe de base de la méthode.

"[BaseClass]::Now()     => $([BaseClass]::Now())"
"[DerivedClassA]::Now() => $([DerivedClassA]::Now())"
"[DerivedClassB]::Now() => $([DerivedClassB]::Now())"
"[DerivedClassC]::Now() => $([DerivedClassC]::Now())"
[BaseClass]::Now()     => 11/06/2023 09:41:23
[DerivedClassA]::Now() => 11/06/2023 09:41:23
[DerivedClassB]::Now() => 11/06/2023 09:41:23
[DerivedClassC]::Now() => 11/06/2023 09:41:23

Le bloc suivant appelle la DaysAgo() méthode statique de chaque classe. Seule la sortie de DerivedClassB est différente, car elle dépasse l’implémentation de base.

"[BaseClass]::DaysAgo(3)     => $([BaseClass]::DaysAgo(3))"
"[DerivedClassA]::DaysAgo(3) => $([DerivedClassA]::DaysAgo(3))"
"[DerivedClassB]::DaysAgo(3) => $([DerivedClassB]::DaysAgo(3))"
"[DerivedClassC]::DaysAgo(3) => $([DerivedClassC]::DaysAgo(3))"
[BaseClass]::DaysAgo(3)     => 11/03/2023 09:41:38
[DerivedClassA]::DaysAgo(3) => 11/03/2023 09:41:38
[DerivedClassB]::DaysAgo(3) => 2023-11-03
[DerivedClassC]::DaysAgo(3) => 11/03/2023 09:41:38

Le bloc suivant montre la présentation de chaîne d’une nouvelle instance pour chaque classe. La représentation de DerivedClassB est différente, car elle dépasse la ToString() méthode d’instance.

"`$base = [BaseClass]::New()     => $($base = [BaseClass]::New(); $base)"
"`$a    = [DerivedClassA]::New() => $($a = [DerivedClassA]::New(); $a)"
"`$b    = [DerivedClassB]::New() => $($b = [DerivedClassB]::New(); $b)"
"`$c    = [DerivedClassC]::New() => $($c = [DerivedClassC]::New(); $c)"
$base = [BaseClass]::New()     => 11/6/2023 9:44:57 AM
$a    = [DerivedClassA]::New() => 11/6/2023 9:44:57 AM
$b    = [DerivedClassB]::New() => 2023-11-06
$c    = [DerivedClassC]::New() => 11/6/2023 9:44:57 AM

Le bloc suivant appelle la SetTimeStamp() méthode d’instance pour chaque instance, en définissant la propriété TimeStamp sur une date spécifique. Chaque instance a la même date, car aucune des classes dérivées ne remplace la surcharge paramétrable pour la méthode.

[datetime]$Stamp = '2024-10-31'
"`$base.SetTimeStamp(`$Stamp) => $($base.SetTimeStamp($Stamp) ; $base)"
"`$a.SetTimeStamp(`$Stamp)    => $($a.SetTimeStamp($Stamp); $a)"
"`$b.SetTimeStamp(`$Stamp)    => $($b.SetTimeStamp($Stamp); $b)"
"`$c.SetTimeStamp(`$Stamp)    => $($c.SetTimeStamp($Stamp); $c)"
$base.SetTimeStamp($Stamp) => 10/31/2024 12:00:00 AM
$a.SetTimeStamp($Stamp)    => 10/31/2024 12:00:00 AM
$b.SetTimeStamp($Stamp)    => 2024-10-31
$c.SetTimeStamp($Stamp)    => 10/31/2024 12:00:00 AM

Le dernier appel de SetTimeStamp() bloc sans aucun paramètre. La sortie indique que la valeur de l’instance DerivedClassC est définie sur 10 jours avant les autres.

"`$base.SetTimeStamp() => $($base.SetTimeStamp() ; $base)"
"`$a.SetTimeStamp()    => $($a.SetTimeStamp(); $a)"
"`$b.SetTimeStamp()    => $($b.SetTimeStamp(); $b)"
"`$c.SetTimeStamp()    => $($c.SetTimeStamp(); $c)"
$base.SetTimeStamp() => 11/6/2023 9:53:58 AM
$a.SetTimeStamp()    => 11/6/2023 9:53:58 AM
$b.SetTimeStamp()    => 2023-11-06
$c.SetTimeStamp()    => 10/27/2023 9:53:58 AM

Définition de méthodes d’instance avec Update-TypeData

Au-delà de déclarer des méthodes directement dans la définition de classe, vous pouvez définir des méthodes 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 <ClassName> {
    static [hashtable[]] $MemberDefinitions = @(
        @{
            MemberName = '<MethodName>'
            MemberType = 'ScriptMethod'
            Value      = {
              param(<method-parameters>)

              <method-body>
            }
        }
    )

    static <ClassName>() {
        $TypeName = [<ClassName>].Name
        foreach ($Definition in [<ClassName>]::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 s’exécute 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.

Définition de méthodes avec des valeurs de paramètre par défaut et des attributs de validation

Les méthodes définies directement dans une déclaration de classe ne peuvent pas définir de valeurs par défaut ni d’attributs de validation sur les paramètres de méthode. Pour définir des méthodes de classe avec des valeurs par défaut ou des attributs de validation, elles doivent être définies en tant que membres ScriptMethod .

Dans cet exemple, la classe CardDeck définit une méthode qui utilise à Draw() la fois un attribut de validation et une valeur par défaut pour le paramètre Count.

class CookieJar {
    [int] $Cookies = 12

    static [hashtable[]] $MemberDefinitions = @(
        @{
            MemberName = 'Eat'
            MemberType = 'ScriptMethod'
            Value      = {
                param(
                    [ValidateScript({ $_ -ge 1 -and $_ -le $this.Cookies })]
                    [int] $Count = 1
                )

                $this.Cookies -= $Count
                if ($Count -eq 1) {
                    "You ate 1 cookie. There are $($this.Cookies) left."
                } else {
                    "You ate $Count cookies. There are $($this.Cookies) left."
                }
            }
        }
    )

    static CookieJar() {
        $TypeName = [CookieJar].Name
        foreach ($Definition in [CookieJar]::MemberDefinitions) {
            Update-TypeData -TypeName $TypeName @Definition
        }
    }
}

$Jar = [CookieJar]::new()
$Jar.Eat(1)
$Jar.Eat()
$Jar.Eat(20)
$Jar.Eat(6)
You ate 1 cookie. There are 11 left.

You ate 1 cookie. There are 10 left.

MethodInvocationException:
Line |
  36 |  $Jar.Eat(20)
     |  ~~~~~~~~~~~~
     | Exception calling "Eat" with "1" argument(s): "The attribute
     | cannot be added because variable Count with value 20 would no
     | longer be valid."

You ate 6 cookies. There are 4 left.

Remarque

Bien que ce modèle fonctionne pour les attributs de validation, notez que l’exception est trompeuse, en référençant une incapacité à ajouter un attribut. Il peut s’agir d’une meilleure expérience utilisateur pour vérifier explicitement la valeur du paramètre et déclencher une erreur significative à la place. De cette façon, les utilisateurs peuvent comprendre pourquoi ils voient l’erreur et ce qu’il faut faire à ce sujet.

Limites

Les méthodes de classe PowerShell présentent les limitations suivantes :

  • Les paramètres de méthode ne peuvent pas utiliser d’attributs, y compris les attributs de validation.

    Solution de contournement : réaffectez les paramètres dans le corps de la méthode avec l’attribut de validation ou définissez la méthode dans le constructeur statique avec l’applet Update-TypeData de commande.

  • Les paramètres de méthode ne peuvent pas définir de valeurs par défaut. Les paramètres sont toujours obligatoires.

    Solution de contournement : définissez la méthode dans le constructeur statique avec l’applet de Update-TypeData commande.

  • Les méthodes sont toujours publiques, même lorsqu’elles sont masquées. Elles peuvent être remplacées lorsque la classe est héritée.

    Solution de contournement : aucune.

  • Si une surcharge d’une méthode est masquée, chaque surcharge de cette méthode est traitée comme masquée également.

    Solution de contournement : aucune.

Voir aussi