about_Classes_Methods

Rövid leírás

Ismerteti, hogyan definiálhat metódusokat a PowerShell-osztályokhoz.

Hosszú leírás

A metódusok határozzák meg az osztály által végrehajtható műveleteket. A metódusok olyan paramétereket is használhatnak, amelyek bemeneti adatokat adnak meg. A metódusok mindig meghatároznak egy kimeneti típust. Ha egy metódus nem ad vissza kimenetet, akkor a Void kimeneti típussal kell rendelkeznie. Ha egy metódus nem határoz meg explicit módon kimeneti típust, a metódus kimeneti típusa Üres.

Az osztálymetódusokban a rendszer csak az utasításban megadott objektumokat küldi el a return folyamatnak. A kód nem ad véletlen kimenetet a folyamatnak.

Feljegyzés

Ez alapvetően eltér attól, ahogyan a PowerShell-függvények kezelik a kimenetet, ahol minden a folyamathoz kerül.

Az osztálymetóduson belülről a hibastreambe írt nem ismétlődő hibák nem lesznek átadva. A megszüntetési hiba felszínre hozásához használnia throw kell. A Write-* parancsmagok használatával továbbra is írhat a PowerShell kimeneti adatfolyamaiba egy osztálymetóduson belül. A parancsmagok tiszteletben tartják a hívó hatókör beállítási változóit . Kerülje azonban a Write-* parancsmagok használatát, hogy a metódus csak az utasítással adja ki az return objektumokat.

Az osztálymetódusok az automatikus változóval hivatkozhatnak az osztályobjektum aktuális példányára az $this aktuális osztályban definiált tulajdonságok és egyéb metódusok eléréséhez. Az $this automatikus változó statikus metódusokban nem érhető el.

Az osztály metódusai tetszőleges számú attribútummal rendelkezhetnek, beleértve a rejtett és statikus attribútumokat is.

Syntax

Az osztály metódusai a következő szintaxisokat használják:

Egysoros szintaxis

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

Többsoros szintaxis

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

Példák

1. példa – Minimális metódusdefiníció

Az GetVolume() ExampleCube1 osztály metódusa a kocka kötetét adja vissza. A kimeneti típust lebegő számként határozza meg, és a példány Magasság, Hossz és Szélesség tulajdonságának szorzásának eredményét adja vissza.

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

2. példa – Metódus paraméterekkel

A GeWeight() módszer a kocka sűrűségéhez egy lebegőszám bemenetet használ, és a kocka tömegét adja vissza, amely a sűrűség és a sűrűség szorzataként kiszámított mennyiség.

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

3. példa – Metódus kimenet nélkül

Ez a példa a Validate() system.void kimenettípusú metódust határozza meg. Ez a metódus nem ad vissza kimenetet. Ha az ellenőrzés sikertelen, az hibát jelez. A GetVolume() metódus meghívja Validate() a kocka kötetének kiszámítása előtt. Ha az ellenőrzés sikertelen, a metódus a számítás előtt leáll.

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.

A metódus kivételt eredményez, mert a Magasság és szélesség tulajdonságok érvénytelenek, így az osztály nem számíthatja ki az aktuális kötetet.

4. példa – Túlterheléses statikus módszer

A ExampleCube4 osztály két túlterheléssel definiálja a statikus metódust GetVolume() . Az első túlterhelés paraméterekkel rendelkezik a kocka méreteihez, és egy jelölő jelzi, hogy a metódusnak ellenőriznie kell-e a bemenetet.

A második túlterhelés csak a numerikus bemeneteket tartalmazza. Úgy hívja az első túlterhelést $Static , mint $true. A második túlterhelés lehetővé teszi a felhasználók számára a metódus meghívását anélkül, hogy mindig meg kellene határozniuk, hogy szigorúan ellenőrizni kell-e a bemenetet.

Az osztály példányként (nemsztatikus) is definiálható GetVolume() . Ez a metódus meghívja a második statikus túlterhelést, biztosítva, hogy a példány GetVolume() metódusa mindig ellenőrizze a kocka dimenzióit a kimeneti érték visszaadása előtt.

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.

A metódusdefiníciók részletes üzenetei bemutatják, hogyan hívja meg a statikus metódust $this.GetVolume() a kezdeti hívás.

A statikus metódus meghívása közvetlenül a Szigorú paraméterrel a kötet visszatérési 0 értékeként$false.

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

Metódus-aláírások és túlterhelések

Minden osztálymetódus egyedi aláírással rendelkezik, amely meghatározza a metódus meghívásának módját. A metódus kimeneti típusa, neve és paraméterei határozzák meg a metódus aláírását.

Ha egy osztály több azonos nevű metódust határoz meg, a metódus definíciói túlterhelések. A metódus túlterhelésének különböző paraméterekkel kell rendelkeznie. A metódusok nem definiálhatnak két azonos paraméterekkel rendelkező implementációt, még akkor sem, ha a kimeneti típusok eltérőek.

Az alábbi osztály két metódust határoz meg, Shuffle() és Deal()a . A Deal() metódus két túlterhelést határoz meg, az egyik paraméter nélkül, a másikat a Count paraméterrel.

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() })
    }
}

Metódus kimenete

Alapértelmezés szerint a metódusok nem rendelkeznek kimenettel. Ha a metódus-aláírás a Voidtól eltérő explicit kimeneti típust is tartalmaz, a metódusnak egy ilyen típusú objektumot kell visszaadnia. A metódusok nem bocsátanak ki kimenetet, kivéve ha a return kulcsszó explicit módon visszaad egy objektumot.

Metódusparaméterek

Az osztálymetódusok meghatározhatják a metódus törzsében használandó bemeneti paramétereket. A metódusparaméterek zárójelek közé vannak zárva, és vesszővel vannak elválasztva. Az üres zárójelek azt jelzik, hogy a metódus nem igényel paramétereket.

A paraméterek egy vagy több sorban határozhatók meg. Az alábbi blokkok a metódusparaméterek szintaxisát mutatják be.

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

A metódusparaméterek erősen beírhatók. Ha egy paraméter nincs begépelve, a metódus az adott paraméter bármely objektumát elfogadja. Ha a paraméter be van adva, a metódus megpróbálja a paraméter értékét a megfelelő típusra konvertálni, kivételt eredményezve, ha a bemenet nem konvertálható.

A metódusparaméterek nem definiálhatnak alapértelmezett értékeket. Minden metódusparaméter kötelező.

A metódusparaméterek nem tartalmazhatnak más attribútumokat. Ez megakadályozza, hogy a metódusok paramétereket használjanak az Validate* attribútumokkal. Az érvényesítési attribútumokkal kapcsolatos további információkért lásd : about_Functions_Advanced_Parameters.

Az alábbi minták egyikével érvényesítést adhat hozzá a metódusparaméterekhez:

  1. A paraméterek hozzárendelése ugyanazokhoz a változókhoz a szükséges érvényesítési attribútumokkal. Ez a statikus és a példánymetelyek esetében is működik. Példa erre a mintára: 4. példa.
  2. Olyan paraméter definiálására ScriptMethod használhatóUpdate-TypeData, amely közvetlenül érvényesítési attribútumokat használ a paramétereken. Ez csak a példánymetóták esetében működik. További információ: A példány metódusainak definiálása az Update-TypeData szakaszban.

Automatikus változók a metódusokban

A metódusokban nem minden automatikus változó érhető el. Az alábbi lista automatikus változókat és javaslatokat tartalmaz arra vonatkozóan, hogy használhatók-e és hogyan a PowerShell-osztály módszereiben. A listában nem szereplő automatikus változók nem érhetők el az osztálymódszerek számára.

  • $? - Hozzáférés a szokásos módon.
  • $_ - Hozzáférés a szokásos módon.
  • $args – Használja inkább az explicit paraméterváltozókat.
  • $ConsoleFileName - Hozzáférés helyett $Script:ConsoleFileName .
  • $Error - Hozzáférés a szokásos módon.
  • $EnabledExperimentalFeatures - Hozzáférés helyett $Script:EnabledExperimentalFeatures .
  • $Event - Hozzáférés a szokásos módon.
  • $EventArgs - Hozzáférés a szokásos módon.
  • $EventSubscriber - Hozzáférés a szokásos módon.
  • $ExecutionContext - Hozzáférés helyett $Script:ExecutionContext .
  • $false - Hozzáférés a szokásos módon.
  • $foreach - Hozzáférés a szokásos módon.
  • $HOME - Hozzáférés helyett $Script:HOME .
  • $Host - Hozzáférés helyett $Script:Host .
  • $input – Használja inkább az explicit paraméterváltozókat.
  • $IsCoreCLR - Hozzáférés helyett $Script:IsCoreCLR .
  • $IsLinux - Hozzáférés helyett $Script:IsLinux .
  • $IsMacOS - Hozzáférés helyett $Script:IsMacOS .
  • $IsWindows - Hozzáférés helyett $Script:IsWindows .
  • $LASTEXITCODE - Hozzáférés a szokásos módon.
  • $Matches - Hozzáférés a szokásos módon.
  • $MyInvocation - Hozzáférés a szokásos módon.
  • $NestedPromptLevel - Hozzáférés a szokásos módon.
  • $null - Hozzáférés a szokásos módon.
  • $PID - Hozzáférés helyett $Script:PID .
  • $PROFILE - Hozzáférés helyett $Script:PROFILE .
  • $PSBoundParameters - Ne használja ezt a változót. Parancsmagokhoz és függvényekhez készült. Az osztályban való használat váratlan mellékhatásokat okozhat.
  • $PSCmdlet - Ne használja ezt a változót. Parancsmagokhoz és függvényekhez készült. Az osztályban való használat váratlan mellékhatásokat okozhat.
  • $PSCommandPath - Hozzáférés a szokásos módon.
  • $PSCulture - Hozzáférés helyett $Script:PSCulture .
  • $PSEdition - Hozzáférés helyett $Script:PSEdition .
  • $PSHOME - Hozzáférés helyett $Script:PSHOME .
  • $PSItem - Hozzáférés a szokásos módon.
  • $PSScriptRoot - Hozzáférés a szokásos módon.
  • $PSSenderInfo - Hozzáférés helyett $Script:PSSenderInfo .
  • $PSUICulture - Hozzáférés helyett $Script:PSUICulture .
  • $PSVersionTable - Hozzáférés helyett $Script:PSVersionTable .
  • $PWD - Hozzáférés a szokásos módon.
  • $Sender - Hozzáférés a szokásos módon.
  • $ShellId - Hozzáférés helyett $Script:ShellId .
  • $StackTrace - Hozzáférés a szokásos módon.
  • $switch - Hozzáférés a szokásos módon.
  • $this - Hozzáférés a szokásos módon. Egy osztálymetódusban $this mindig az osztály aktuális példánya. Ezzel az osztálytulajdonságokat és metódusokat is elérheti. Statikus metódusokban nem érhető el.
  • $true - Hozzáférés a szokásos módon.

Az automatikus változókkal kapcsolatos további információkért lásd: about_Automatic_Variables.

Rejtett metódusok

Az osztály metódusait elrejtheti úgy, hogy a kulcsszóval deklarálja őket hidden . A rejtett osztály metódusai a következők:

  • A parancsmag által Get-Member visszaadott osztálytagok listájában nem szerepel. Rejtett metódusok Get-Membermegjelenítéséhez használja a Force paramétert.
  • A lapkizárás vagy az IntelliSense csak akkor jelenik meg, ha a befejezés a rejtett metódust meghatározó osztályban történik.
  • Az osztály nyilvános tagjai. Meghívhatók és örökölhetők. Egy metódus elrejtése nem teszi privátsá. Csak az előző pontokban leírtak szerint rejti el a metódust.

Feljegyzés

Ha elrejti a metódus túlterhelését, a rendszer eltávolítja a metódust az IntelliSense-ből, a befejezési eredményeket és az alapértelmezett kimenetet Get-Member.

A kulcsszóval kapcsolatos további információkért lásd: hidden about_Hidden.

Statikus metódusok

A metódust úgy határozhatja meg, hogy az osztály példányai helyett az osztályhoz tartozik. Ehhez deklarálhatja a metódust a static kulcsszóval. Statikus osztály módszerei:

  • Mindig elérhetőek, az osztály példányosításától függetlenül.
  • Az osztály összes példánya meg van osztva.
  • Mindig elérhetőek.
  • Az osztály példánytulajdonságai nem érhetők el. Csak statikus tulajdonságokhoz férhetnek hozzá.
  • Élőben a teljes munkamenethez.

Származtatott osztály metódusai

Amikor egy osztály egy alaposztályból származik, örökli az alaposztály metódusait és azok túlterheléseit. Az alaposztályon definiált metódusterhelések, beleértve a rejtett metódusokat is, elérhetők a származtatott osztályban.

A származtatott osztályok felülbírálhatják az örökölt metódusok túlterhelését, ha újradefiniálják azt az osztálydefinícióban. A túlterhelés felülbírálásához a paramétertípusoknak meg kell egyeznie az alaposztály típusával. A túlterhelés kimeneti típusa eltérő lehet.

A konstruktorokkal ellentétben a metódusok nem használhatják a szintaxist a : base(<parameters>) metódus alaposztály-túlterhelésének meghívására. A származtatott osztály újradefiniált túlterhelése teljesen felülírja az alaposztály által definiált túlterhelést.

Az alábbi példa a származtatott osztályok statikus és példánymetelyeinek viselkedését mutatja be.

Az alaposztály a következőket határozza meg:

  • Az aktuális idő visszaadásának és DaysAgo() egy múltbeli dátum visszaadásának statikus módszereiNow().
  • A TimeStamp példánytulajdonság és egy példánymetódus, amely az adott tulajdonság sztring-ábrázolását ToString() adja vissza. Ez biztosítja, hogy amikor egy példányt használ egy sztringben, akkor az osztálynév helyett datetime sztringgé alakul át.
  • A példány metódusa SetTimeStamp() két túlterheléssel. Ha a metódus paraméterek nélkül van meghívva, a TimeStamp értékét az aktuális időpontra állítja. Ha a metódust DateTime-tal hívják meg, a TimeStamp értékét erre az értékre állítja be.
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()
    }
}

A következő blokk a BaseClass-ból származtatott osztályokat határozza meg:

  • A DerivedClassA felülbírálások nélkül örökli a BaseClass-t.
  • A DerivedClassB felülbírálja a DaysAgo() statikus metódust, hogy a DateTime objektum helyett sztring-ábrázolást adjon vissza. Felülbírálja a ToString() példány metódusát is, hogy az időbélyeget ISO8601 dátumsztringként adja vissza.
  • A DerivedClassC felülbírálja a SetTimeStamp() metódus paraméter nélküli túlterhelését, így az időbélyeg paraméter nélküli beállítása a dátumot 10 nappal az aktuális dátum előtt állítja be.
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))
    }
}

Az alábbi blokk a meghatározott osztályok statikus Now() metódusának kimenetét mutatja. A kimenet minden osztály esetében ugyanaz, mert a származtatott osztályok nem bírálják felül a metódus alaposztály-implementációját.

"[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

A következő blokk meghívja az DaysAgo() egyes osztályok statikus metódusát. Csak a DerivedClassB kimenete különbözik, mert felülírja az alap implementációt.

"[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

Az alábbi blokk az egyes osztályokhoz tartozó új példány sztringbemutatóját mutatja be. A DerivedClassB reprezentációja eltérő, mert felülírja a ToString() példánymetódust.

"`$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

A következő blokk meghívja az SetTimeStamp() egyes példányok példánymetódusát, és beállítja a TimeStamp tulajdonságot egy adott dátumra. Minden példány ugyanazzal a dátummal rendelkezik, mert egyik származtatott osztály sem bírálja felül a metódus paraméteres túlterhelését.

[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

Az utolsó blokkhívások SetTimeStamp() paraméterek nélkül. A kimenet azt mutatja, hogy a DerivedClassC-példány értéke 10 nappal a többiek előtt van beállítva.

"`$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

Példánymódszerek definiálása az Update-TypeData használatával

A metódusok közvetlenül az osztálydefinícióban való deklarálásán túl a parancsmag használatával Update-TypeData definiálhat metódusokat egy osztály példányaihoz a statikus konstruktorban.

Használja ezt a kódrészletet a minta kiindulópontjaként. Szükség szerint cserélje le a helyőrző szöveget szögletes zárójelekben.

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
        }
    }
}

Tipp.

A Add-Member parancsmag tulajdonságokat és metódusokat adhat hozzá egy osztályhoz nem statikus konstruktorokban, de a parancsmag minden alkalommal fut, amikor a konstruktort meghívják. A Update-TypeData statikus konstruktor használata biztosítja, hogy a tagok osztályhoz való hozzáadásához használt kódnak csak egyszer kell futnia egy munkamenetben.

Metódusok definiálása alapértelmezett paraméterértékekkel és érvényesítési attribútumokkal

Az osztálydeklarációban közvetlenül definiált metódusok nem definiálhatnak alapértelmezett értékeket vagy érvényesítési attribútumokat a metódusparamétereken. Az alapértelmezett értékekkel vagy érvényesítési attribútumokkal rendelkező osztálymetódusok definiálásához ScriptMethod-tagokként kell definiálni őket.

Ebben a példában a CardDeck osztály egy olyan metódust Draw() határoz meg, amely egy érvényesítési attribútumot és egy alapértelmezett értéket is használ a Count paraméterhez.

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.

Feljegyzés

Bár ez a minta érvényesítési attribútumok esetében működik, figyelje meg, hogy a kivétel félrevezető, ezért nem lehet attribútumot hozzáadni. Jobb felhasználói élmény lehet, ha explicit módon ellenőrzi a paraméter értékét, és ehelyett értelmes hibát jelez. Így a felhasználók megérthetik, hogy miért látja a hibát, és mit kell tenni vele.

Korlátozások

A PowerShell-osztály metódusai a következő korlátozásokkal rendelkeznek:

  • A metódusparaméterek nem használhatnak attribútumokat, beleértve az érvényesítési attribútumokat is.

    Megkerülő megoldás: Rendelje újra a metódus törzsének paramétereit az érvényesítési attribútummal, vagy határozza meg a metódust a statikus konstruktorban a Update-TypeData parancsmaggal.

  • A metódusparaméterek nem definiálhatnak alapértelmezett értékeket. A paraméterek mindig kötelezőek.

    Megkerülő megoldás: Adja meg a metódust a statikus konstruktorban a Update-TypeData parancsmaggal.

  • A metódusok mindig nyilvánosak, még akkor is, ha rejtve vannak. Felül lehet őket bírálni, ha az osztály öröklődik.

    Megkerülő megoldás: Nincs.

  • Ha egy metódus túlterhelése rejtett, a metódus minden túlterhelése is rejtettként lesz kezelve.

    Megkerülő megoldás: Nincs.

Lásd még