about_Classes_Methods

Deskripsi singkat

Menjelaskan cara menentukan metode untuk kelas PowerShell.

Deskripsi panjang

Metode menentukan tindakan yang dapat dilakukan oleh kelas. Metode dapat mengambil parameter yang menentukan data input. Metode selalu menentukan jenis output. Jika metode tidak mengembalikan output apa pun, metode tersebut harus memiliki jenis output Void . Jika metode tidak secara eksplisit menentukan jenis output, jenis output metode adalah Void.

Dalam metode kelas, tidak ada objek yang dikirim ke alur kecuali yang ditentukan dalam return pernyataan. Tidak ada output yang tidak disengaja ke alur dari kode.

Catatan

Ini pada dasarnya berbeda dari bagaimana fungsi PowerShell menangani output, di mana semuanya masuk ke alur.

Kesalahan nonterminasi yang ditulis ke aliran kesalahan dari dalam metode kelas tidak diteruskan. Anda harus menggunakan throw untuk menampilkan kesalahan yang mengakhiri. Write-* Dengan menggunakan cmdlet, Anda masih dapat menulis ke aliran output PowerShell dari dalam metode kelas. Cmdlet menghormati variabel preferensi dalam cakupan panggilan. Namun, Anda harus menghindari penggunaan Write-* cmdlet sehingga metode hanya menghasilkan objek menggunakan return pernyataan .

Metode kelas dapat mereferensikan instans objek kelas saat ini dengan menggunakan $this variabel otomatis untuk mengakses properti dan metode lain yang ditentukan di kelas saat ini. Variabel $this otomatis tidak tersedia dalam metode statis.

Metode kelas dapat memiliki sejumlah atribut, termasuk atribut tersembunyi dan statis .

Sintaks

Metode kelas menggunakan sintaks berikut:

Sintaksis satu baris

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

Sintaks multibaris

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

Contoh

Contoh 1 - Definisi metode minimal

Metode GetVolume() kelas ExampleCube1 mengembalikan volume kubus. Ini mendefinisikan jenis output sebagai angka mengambang dan mengembalikan hasil mengalikan properti Tinggi, Panjang, dan Lebar instans.

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

Contoh 2 - Metode dengan parameter

Metode ini GeWeight() mengambil input angka mengambang untuk kepadatan kubus dan mengembalikan berat kubus, dihitung sebagai volume dikalikan dengan kepadatan.

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

Contoh 3 - Metode tanpa output

Contoh ini mendefinisikan Validate() metode dengan jenis output sebagai System.Void. Metode ini tidak mengembalikan output. Sebaliknya, jika validasi gagal, ia melemparkan kesalahan. Metode memanggil GetVolume()Validate() sebelum menghitung volume kubus. Jika validasi gagal, metode berakhir sebelum penghitungan.

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.

Metode ini melemparkan pengecualian karena properti Tinggi dan Lebar tidak valid, mencegah kelas menghitung volume saat ini.

Contoh 4 - Metode statis dengan kelebihan beban

Kelas ExampleCube4 mendefinisikan metode GetVolume() statis dengan dua kelebihan beban. Kelebihan beban pertama memiliki parameter untuk dimensi kubus dan bendera untuk menunjukkan apakah metode harus memvalidasi input.

Kelebihan beban kedua hanya mencakup input numerik. Ini menyebut kelebihan beban pertama dengan $Static sebagai $true. Kelebihan beban kedua memberi pengguna cara untuk memanggil metode tanpa selalu harus menentukan apakah akan memvalidasi input secara ketat.

Kelas ini juga mendefinisikan sebagai metode instans GetVolume() (nonstatis). Metode ini memanggil kelebihan beban statis kedua, memastikan bahwa metode instans GetVolume() selalu memvalidasi dimensi kubus sebelum mengembalikan nilai output.

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.

Pesan verbose dalam definisi metode menunjukkan bagaimana panggilan awal untuk $this.GetVolume() memanggil metode statis.

Memanggil metode statis secara langsung dengan parameter Ketat sebagai $false pengembalian 0 untuk volume.

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

Tanda tangan metode dan kelebihan beban

Setiap metode kelas memiliki tanda tangan unik yang menentukan cara memanggil metode . Jenis output, nama, dan parameter metode menentukan tanda tangan metode.

Ketika kelas mendefinisikan lebih dari satu metode dengan nama yang sama, definisi metode tersebut kelebihan beban. Kelebihan beban untuk metode harus memiliki parameter yang berbeda. Metode tidak dapat menentukan dua implementasi dengan parameter yang sama, bahkan jika jenis output berbeda.

Kelas berikut mendefinisikan dua metode, Shuffle() dan Deal(). Metode ini Deal() mendefinisikan dua kelebihan beban, satu tanpa parameter apa pun dan yang lain dengan parameter Hitung .

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

Output metode

Secara default, metode tidak memiliki output apa pun. Jika tanda tangan metode menyertakan jenis output eksplisit selain Void, metode harus mengembalikan objek jenis tersebut. Metode tidak mengeluarkan output apa pun kecuali ketika kata kunci secara eksplisit return mengembalikan objek.

Parameter metode

Metode kelas dapat menentukan parameter input yang akan digunakan dalam isi metode. Parameter metode diapit dalam tanda kurung dan dipisahkan dengan koma. Tanda kurung kosong menunjukkan bahwa metode tidak memerlukan parameter.

Parameter dapat ditentukan pada satu baris atau beberapa baris. Blok berikut menunjukkan sintaks untuk parameter metode.

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

Parameter metode dapat ditik dengan kuat. Jika parameter tidak ditik, metode menerima objek apa pun untuk parameter tersebut. Jika parameter diketik, metode mencoba mengonversi nilai untuk parameter tersebut ke jenis yang benar, melemparkan pengecualian jika input tidak dapat dikonversi.

Parameter metode tidak dapat menentukan nilai default. Semua parameter metode bersifat wajib.

Parameter metode tidak dapat memiliki atribut lain. Ini mencegah metode menggunakan parameter dengan Validate* atribut . Untuk informasi selengkapnya tentang atribut validasi, lihat about_Functions_Advanced_Parameters.

Anda dapat menggunakan salah satu pola berikut untuk menambahkan validasi ke parameter metode:

  1. Menetapkan ulang parameter ke variabel yang sama dengan atribut validasi yang diperlukan. Ini berfungsi untuk metode statis dan instans. Untuk contoh pola ini, lihat Contoh 4.
  2. Gunakan Update-TypeData untuk menentukan ScriptMethod yang menggunakan atribut validasi pada parameter secara langsung. Ini hanya berfungsi untuk metode instans. Untuk informasi selengkapnya, lihat bagian Menentukan metode instans dengan Update-TypeData .

Variabel otomatis dalam metode

Tidak semua variabel otomatis tersedia dalam metode. Daftar berikut ini mencakup variabel dan saran otomatis untuk apakah dan cara menggunakannya dalam metode kelas PowerShell. Variabel otomatis yang tidak disertakan dalam daftar tidak tersedia untuk metode kelas.

  • $_ - Akses seperti biasa.
  • $args - Gunakan variabel parameter eksplisit sebagai gantinya.
  • $ConsoleFileName - Akses sebagai $Script:ConsoleFileName gantinya.
  • $Error - Akses seperti biasa.
  • $EnabledExperimentalFeatures - Akses sebagai $Script:EnabledExperimentalFeatures gantinya.
  • $Event - Akses seperti biasa.
  • $EventArgs - Akses seperti biasa.
  • $EventSubscriber - Akses seperti biasa.
  • $ExecutionContext - Akses sebagai $Script:ExecutionContext gantinya.
  • $false - Akses seperti biasa.
  • $foreach - Akses seperti biasa.
  • $HOME - Akses sebagai $Script:HOME gantinya.
  • $Host - Akses sebagai $Script:Host gantinya.
  • $input - Gunakan variabel parameter eksplisit sebagai gantinya.
  • $IsCoreCLR - Akses sebagai $Script:IsCoreCLR gantinya.
  • $IsLinux - Akses sebagai $Script:IsLinux gantinya.
  • $IsMacOS - Akses sebagai $Script:IsMacOS gantinya.
  • $IsWindows - Akses sebagai $Script:IsWindows gantinya.
  • $LASTEXITCODE - Akses seperti biasa.
  • $Matches - Akses seperti biasa.
  • $MyInvocation - Akses seperti biasa.
  • $NestedPromptLevel - Akses seperti biasa.
  • $null - Akses seperti biasa.
  • $PID - Akses sebagai $Script:PID gantinya.
  • $PROFILE - Akses sebagai $Script:PROFILE gantinya.
  • $PSBoundParameters - Jangan gunakan variabel ini. Ini ditujukan untuk cmdlet dan fungsi. Menggunakannya di kelas mungkin memiliki efek samping yang tidak terduga.
  • $PSCmdlet - Jangan gunakan variabel ini. Ini ditujukan untuk cmdlet dan fungsi. Menggunakannya di kelas mungkin memiliki efek samping yang tidak terduga.
  • $PSCommandPath - Akses seperti biasa.
  • $PSCulture - Akses sebagai $Script:PSCulture gantinya.
  • $PSEdition - Akses sebagai $Script:PSEdition gantinya.
  • $PSHOME - Akses sebagai $Script:PSHOME gantinya.
  • $PSItem - Akses seperti biasa.
  • $PSScriptRoot - Akses seperti biasa.
  • $PSSenderInfo - Akses sebagai $Script:PSSenderInfo gantinya.
  • $PSUICulture - Akses sebagai $Script:PSUICulture gantinya.
  • $PSVersionTable - Akses sebagai $Script:PSVersionTable gantinya.
  • $PWD - Akses seperti biasa.
  • $Sender - Akses seperti biasa.
  • $ShellId - Akses sebagai $Script:ShellId gantinya.
  • $StackTrace - Akses seperti biasa.
  • $switch - Akses seperti biasa.
  • $this - Akses seperti biasa. Dalam metode kelas, $this selalu merupakan instans kelas saat ini. Anda dapat mengakses properti dan metode kelas dengannya. Ini tidak tersedia dalam metode statis.
  • $true - Akses seperti biasa.

Untuk informasi selengkapnya tentang variabel otomatis, lihat about_Automatic_Variables.

Metode tersembunyi

Anda dapat menyembunyikan metode kelas dengan mendeklarasikannya dengan hidden kata kunci. Metode kelas tersembunyi adalah:

  • Tidak termasuk dalam daftar anggota kelas yang Get-Member dikembalikan oleh cmdlet. Untuk menampilkan metode tersembunyi dengan Get-Member, gunakan parameter Force .
  • Tidak ditampilkan dalam penyelesaian tab atau IntelliSense kecuali penyelesaian terjadi di kelas yang menentukan metode tersembunyi.
  • Anggota publik kelas. Mereka dapat dipanggil dan diwariskan. Menyembunyikan metode tidak membuatnya privat. Ini hanya menyembunyikan metode seperti yang dijelaskan di titik-titik sebelumnya.

Catatan

Ketika Anda menyembunyikan kelebihan beban untuk metode , metode tersebut dihapus dari IntelliSense, hasil penyelesaian, dan output default untuk Get-Member.

Untuk informasi selengkapnya tentang hidden kata kunci, lihat about_Hidden.

Metode statis

Anda dapat menentukan metode sebagai milik kelas itu sendiri alih-alih instans kelas dengan mendeklarasikan metode dengan static kata kunci. Metode kelas statis:

  • Selalu tersedia, independen dari instansiasi kelas.
  • Dibagikan di semua instans kelas.
  • Selalu tersedia.
  • Tidak dapat mengakses properti instans kelas. Mereka hanya dapat mengakses properti statis.
  • Hidup untuk seluruh rentang sesi.

Metode kelas turunan

Ketika kelas berasal dari kelas dasar, kelas tersebut mewarisi metode kelas dasar dan kelebihan bebannya. Setiap metode kelebihan beban yang ditentukan pada kelas dasar, termasuk metode tersembunyi, tersedia pada kelas turunan.

Kelas turunan dapat mengambil alih kelebihan metode yang diwariskan dengan mendefinisikannya kembali dalam definisi kelas. Untuk mengambil alih kelebihan beban, jenis parameter harus sama dengan untuk kelas dasar. Jenis output untuk kelebihan beban bisa berbeda.

Tidak seperti konstruktor, metode tidak dapat menggunakan : base(<parameters>) sintaks untuk memanggil kelebihan kelas dasar untuk metode . Kelebihan beban yang ditentukan ulang pada kelas turunan sepenuhnya menggantikan kelebihan beban yang ditentukan oleh kelas dasar.

Contoh berikut menunjukkan perilaku untuk metode statis dan instans pada kelas turunan.

Kelas dasar mendefinisikan:

  • Metode statis Now() untuk mengembalikan waktu saat ini dan DaysAgo() untuk mengembalikan tanggal di masa lalu.
  • Properti instans TimeStamp dan ToString() metode instans yang mengembalikan representasi string properti tersebut. Ini memastikan bahwa ketika instans digunakan dalam string, instans akan dikonversi ke string tanggalwaktu alih-alih nama kelas.
  • Metode SetTimeStamp() instans dengan dua kelebihan beban. Ketika metode dipanggil tanpa parameter, metode mengatur TimeStamp ke waktu saat ini. Ketika metode dipanggil dengan DateTime, metode mengatur TimeStamp ke nilai tersebut.
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()
    }
}

Blok berikutnya mendefinisikan kelas yang berasal dari BaseClass:

  • DerivedClassA mewarisi dari BaseClass tanpa penimpaan apa pun.
  • DerivedClassB mengambil alih DaysAgo() metode statis untuk mengembalikan representasi string alih-alih objek DateTime . Ini juga mengambil alih ToString() metode instans untuk mengembalikan tanda waktu sebagai string tanggal ISO8601.
  • DerivedClassC mengambil alih kelebihan SetTimeStamp() parameter metode sehingga mengatur tanda waktu tanpa parameter menetapkan tanggal ke 10 hari sebelum tanggal saat ini.
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))
    }
}

Blok berikut menunjukkan output metode statis Now() untuk kelas yang ditentukan. Outputnya sama untuk setiap kelas, karena kelas turunan tidak mengambil alih implementasi kelas dasar metode .

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

Blok berikutnya memanggil DaysAgo() metode statis dari setiap kelas. Hanya output untuk DerivedClassB yang berbeda, karena overrode implementasi dasar.

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

Blok berikut menunjukkan presentasi string instans baru untuk setiap kelas. Representasi untuk DerivedClassB berbeda karena melebihi ToString() metode instans.

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

Blok berikutnya memanggil metode instans untuk setiap instans SetTimeStamp() , mengatur properti TimeStamp ke tanggal tertentu. Setiap instans memiliki tanggal yang sama, karena tidak ada kelas turunan yang mengambil alih kelebihan parameter untuk metode tersebut.

[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

Panggilan SetTimeStamp() blok terakhir tanpa parameter apa pun. Output menunjukkan bahwa nilai untuk instans DerivedClassC diatur ke 10 hari sebelum yang lain.

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

Menentukan metode instans dengan Update-TypeData

Selain mendeklarasikan metode langsung dalam definisi kelas, Anda dapat menentukan metode untuk instans kelas di konstruktor statis menggunakan Update-TypeData cmdlet.

Gunakan cuplikan ini sebagai titik awal untuk pola. Ganti teks tempat penampung dalam tanda kurung sudut sesuai kebutuhan.

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

Tip

Add-Member Cmdlet dapat menambahkan properti dan metode ke kelas dalam konstruktor non-statis, tetapi cmdlet berjalan setiap kali konstruktor dipanggil. Menggunakan Update-TypeData dalam konstruktor statis memastikan bahwa kode untuk menambahkan anggota ke kelas hanya perlu berjalan sekali dalam sesi.

Menentukan metode dengan nilai parameter default dan atribut validasi

Metode yang ditentukan langsung dalam deklarasi kelas tidak dapat menentukan nilai default atau atribut validasi pada parameter metode. Untuk menentukan metode kelas dengan nilai default atau atribut validasi, metode tersebut harus didefinisikan sebagai anggota ScriptMethod .

Dalam contoh ini, kelas CardDeck mendefinisikan Draw() metode yang menggunakan atribut validasi dan nilai default untuk parameter Hitung .

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.

Catatan

Meskipun pola ini berfungsi untuk atribut validasi, perhatikan bahwa pengecualian menyesatkan, merujuk ketidakmampuan untuk menambahkan atribut. Ini mungkin pengalaman pengguna yang lebih baik untuk secara eksplisit memeriksa nilai untuk parameter dan menimbulkan kesalahan yang bermakna sebagai gantinya. Dengan begitu, pengguna dapat memahami mengapa mereka melihat kesalahan dan apa yang harus dilakukan tentang hal itu.

Batasan

Metode kelas PowerShell memiliki batasan berikut:

  • Parameter metode tidak dapat menggunakan atribut apa pun, termasuk atribut validasi.

    Solusi sementara: Tetapkan ulang parameter dalam isi metode dengan atribut validasi atau tentukan metode dalam konstruktor statis dengan Update-TypeData cmdlet.

  • Parameter metode tidak dapat menentukan nilai default. Parameter selalu wajib.

    Solusi sementara: Tentukan metode dalam konstruktor statis dengan Update-TypeData cmdlet.

  • Metode selalu bersifat publik, bahkan ketika disembunyikan. Mereka dapat ditimpa ketika kelas diwariskan.

    Penanganan masalah: Tidak ada.

  • Jika ada kelebihan metode yang disembunyikan, setiap kelebihan beban untuk metode tersebut diperlakukan sebagai tersembunyi juga.

    Penanganan masalah: Tidak ada.

Lihat juga