Bagikan melalui


about_Classes

Deskripsi singkat

Menjelaskan bagaimana Anda dapat menggunakan kelas untuk membuat jenis kustom Anda sendiri.

Deskripsi panjang

Dimulai dengan versi 5.0, PowerShell memiliki sintaks formal untuk menentukan kelas dan jenis lain yang ditentukan pengguna. Penambahan kelas memungkinkan pengembang dan profesional TI untuk merangkul PowerShell untuk berbagai kasus penggunaan yang lebih luas.

Deklarasi kelas adalah cetak biru yang digunakan untuk membuat instans objek pada waktu proses. Saat Anda menentukan kelas, nama kelas adalah nama jenisnya. Misalnya, jika Anda mendeklarasikan kelas bernama Perangkat dan menginisialisasi variabel $dev ke instans Perangkat baru, $dev adalah objek atau instans jenis Perangkat. Setiap instans Perangkat dapat memiliki nilai yang berbeda dalam propertinya.

Skenario yang didukung

  • Tentukan jenis kustom di PowerShell menggunakan semantik pemrograman berorientasi objek seperti kelas, properti, metode, pewarisan, dll.
  • Tentukan sumber daya DSC dan jenis terkaitnya menggunakan bahasa PowerShell.
  • Tentukan atribut kustom untuk menghias variabel, parameter, dan definisi jenis kustom.
  • Tentukan pengecualian kustom yang dapat ditangkap dengan nama jenisnya.

Sintaks

Sintaks definisi

Definisi kelas menggunakan sintaks berikut:

class <class-name> [: [<base-class>][,<interface-list>]] {
    [[<attribute>] [hidden] [static] <property-definition> ...]
    [<class-name>([<constructor-argument-list>])
      {<constructor-statement-list>} ...]
    [[<attribute>] [hidden] [static] <method-definition> ...]
}

Sintaksis instansiasi

Untuk membuat instans kelas, gunakan salah satu sintaks berikut:

[$<variable-name> =] New-Object -TypeName <class-name> [
  [-ArgumentList] <constructor-argument-list>]
[$<variable-name> =] [<class-name>]::new([<constructor-argument-list>])
[$<variable-name> =] [<class-name>]@{[<class-property-hashtable>]}

Catatan

Saat menggunakan sintaksis [<class-name>]::new() , tanda kurung di sekitar nama kelas wajib. Tanda kurung sinyal definisi jenis untuk PowerShell.

Sintaksis hashtable hanya berfungsi untuk kelas yang memiliki konstruktor default yang tidak mengharapkan parameter apa pun. Ini membuat instans kelas dengan konstruktor default dan kemudian menetapkan pasangan kunci-nilai ke properti instans. Jika ada kunci dalam hashtable bukan nama properti yang valid, PowerShell akan menimbulkan kesalahan.

Contoh

Contoh 1 - Definisi minimal

Contoh ini menunjukkan sintaks minimum yang diperlukan untuk membuat kelas yang dapat digunakan.

class Device {
    [string]$Brand
}

$dev = [Device]::new()
$dev.Brand = "Fabrikam, Inc."
$dev
Brand
-----
Fabrikam, Inc.

Contoh 2 - Kelas dengan anggota instans

Contoh ini mendefinisikan kelas Buku dengan beberapa properti, konstruktor, dan metode. Setiap anggota yang ditentukan adalah anggota instans , bukan anggota statis. Properti dan metode hanya dapat diakses melalui instans kelas yang dibuat.

class Book {
    # Class properties
    [string]   $Title
    [string]   $Author
    [string]   $Synopsis
    [string]   $Publisher
    [datetime] $PublishDate
    [int]      $PageCount
    [string[]] $Tags
    # Default constructor
    Book() { $this.Init(@{}) }
    # Convenience constructor from hashtable
    Book([hashtable]$Properties) { $this.Init($Properties) }
    # Common constructor for title and author
    Book([string]$Title, [string]$Author) {
        $this.Init(@{Title = $Title; Author = $Author })
    }
    # Shared initializer method
    [void] Init([hashtable]$Properties) {
        foreach ($Property in $Properties.Keys) {
            $this.$Property = $Properties.$Property
        }
    }
    # Method to calculate reading time as 2 minutes per page
    [timespan] GetReadingTime() {
        if ($this.PageCount -le 0) {
            throw 'Unable to determine reading time from page count.'
        }
        $Minutes = $this.PageCount * 2
        return [timespan]::new(0, $Minutes, 0)
    }
    # Method to calculate how long ago a book was published
    [timespan] GetPublishedAge() {
        if (
            $null -eq $this.PublishDate -or
            $this.PublishDate -eq [datetime]::MinValue
        ) { throw 'PublishDate not defined' }

        return (Get-Date) - $this.PublishDate
    }
    # Method to return a string representation of the book
    [string] ToString() {
        return "$($this.Title) by $($this.Author) ($($this.PublishDate.Year))"
    }
}

Cuplikan berikut membuat instans kelas dan menunjukkan bagaimana perilakunya. Setelah membuat instans GetReadingTime() kelas Buku, contoh menggunakan metode dan GetPublishedAge() untuk menulis pesan tentang buku.

$Book = [Book]::new(@{
    Title       = 'The Hobbit'
    Author      = 'J.R.R. Tolkien'
    Publisher   = 'George Allen & Unwin'
    PublishDate = '1937-09-21'
    PageCount   = 310
    Tags        = @('Fantasy', 'Adventure')
})

$Book
$Time = $Book.GetReadingTime()
$Time = @($Time.Hours, 'hours and', $Time.Minutes, 'minutes') -join ' '
$Age  = [Math]::Floor($Book.GetPublishedAge().TotalDays / 365.25)

"It takes $Time to read $Book,`nwhich was published $Age years ago."
Title       : The Hobbit
Author      : J.R.R. Tolkien
Synopsis    :
Publisher   : George Allen & Unwin
PublishDate : 9/21/1937 12:00:00 AM
PageCount   : 310
Tags        : {Fantasy, Adventure}

It takes 10 hours and 20 minutes to read The Hobbit by J.R.R. Tolkien (1937),
which was published 86 years ago.

Contoh 3 - Kelas dengan anggota statis

Kelas BookList dalam contoh ini dibangun pada kelas Buku dalam contoh 2. Meskipun kelas BookList tidak dapat ditandai statis itu sendiri, implementasi hanya mendefinisikan properti statis Buku dan serangkaian metode statis untuk mengelola properti tersebut.

class BookList {
    # Static property to hold the list of books
    static [System.Collections.Generic.List[Book]] $Books
    # Static method to initialize the list of books. Called in the other
    # static methods to avoid needing to explicit initialize the value.
    static [void] Initialize()             { [BookList]::Initialize($false) }
    static [bool] Initialize([bool]$force) {
        if ([BookList]::Books.Count -gt 0 -and -not $force) {
            return $false
        }

        [BookList]::Books = [System.Collections.Generic.List[Book]]::new()

        return $true
    }
    # Ensure a book is valid for the list.
    static [void] Validate([book]$Book) {
        $Prefix = @(
            'Book validation failed: Book must be defined with the Title,'
            'Author, and PublishDate properties, but'
        ) -join ' '
        if ($null -eq $Book) { throw "$Prefix was null" }
        if ([string]::IsNullOrEmpty($Book.Title)) {
            throw "$Prefix Title wasn't defined"
        }
        if ([string]::IsNullOrEmpty($Book.Author)) {
            throw "$Prefix Author wasn't defined"
        }
        if ([datetime]::MinValue -eq $Book.PublishDate) {
            throw "$Prefix PublishDate wasn't defined"
        }
    }
    # Static methods to manage the list of books.
    # Add a book if it's not already in the list.
    static [void] Add([Book]$Book) {
        [BookList]::Initialize()
        [BookList]::Validate($Book)
        if ([BookList]::Books.Contains($Book)) {
            throw "Book '$Book' already in list"
        }

        $FindPredicate = {
            param([Book]$b)

            $b.Title -eq $Book.Title -and
            $b.Author -eq $Book.Author -and
            $b.PublishDate -eq $Book.PublishDate
        }.GetNewClosure()
        if ([BookList]::Books.Find($FindPredicate)) {
            throw "Book '$Book' already in list"
        }

        [BookList]::Books.Add($Book)
    }
    # Clear the list of books.
    static [void] Clear() {
      [BookList]::Initialize()
      [BookList]::Books.Clear()
    }
    # Find a specific book using a filtering scriptblock.
    static [Book] Find([scriptblock]$Predicate) {
        [BookList]::Initialize()
        return [BookList]::Books.Find($Predicate)
    }
    # Find every book matching the filtering scriptblock.
    static [Book[]] FindAll([scriptblock]$Predicate) {
        [BookList]::Initialize()
        return [BookList]::Books.FindAll($Predicate)
    }
    # Remove a specific book.
    static [void] Remove([Book]$Book) {
        [BookList]::Initialize()
        [BookList]::Books.Remove($Book)
    }
    # Remove a book by property value.
    static [void] RemoveBy([string]$Property, [string]$Value) {
        [BookList]::Initialize()
        $Index = [BookList]::Books.FindIndex({
            param($b)
            $b.$Property -eq $Value
        }.GetNewClosure())
        if ($Index -ge 0) {
            [BookList]::Books.RemoveAt($Index)
        }
    }
}

Sekarang setelah BookList ditentukan, buku dari contoh sebelumnya dapat ditambahkan ke daftar.

$null -eq [BookList]::Books

[BookList]::Add($Book)

[BookList]::Books
True

Title       : The Hobbit
Author      : J.R.R. Tolkien
Synopsis    :
Publisher   : George Allen & Unwin
PublishDate : 9/21/1937 12:00:00 AM
PageCount   : 310
Tags        : {Fantasy, Adventure}

Cuplikan berikut memanggil metode statis untuk kelas .

[BookList]::Add([Book]::new(@{
    Title       = 'The Fellowship of the Ring'
    Author      = 'J.R.R. Tolkien'
    Publisher   = 'George Allen & Unwin'
    PublishDate = '1954-07-29'
    PageCount   = 423
    Tags        = @('Fantasy', 'Adventure')
}))

[BookList]::Find({
    param ($b)

    $b.PublishDate -gt '1950-01-01'
}).Title

[BookList]::FindAll({
    param($b)

    $b.Author -match 'Tolkien'
}).Title

[BookList]::Remove($Book)
[BookList]::Books.Title

[BookList]::RemoveBy('Author', 'J.R.R. Tolkien')
"Titles: $([BookList]::Books.Title)"

[BookList]::Add($Book)
[BookList]::Add($Book)
The Fellowship of the Ring

The Hobbit
The Fellowship of the Ring

The Fellowship of the Ring

Titles:

Exception:
Line |
  84 |              throw "Book '$Book' already in list"
     |              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | Book 'The Hobbit by J.R.R. Tolkien (1937)' already in list

Contoh 4 - Definisi kelas dengan dan tanpa afinitas Runspace

Metode ShowRunspaceId() [UnsafeClass] melaporkan ID utas yang berbeda tetapi ID runspace yang sama. Akhirnya, status sesi rusak menyebabkan kesalahan, seperti Global scope cannot be removed.

# Class definition with Runspace affinity (default behavior)
class UnsafeClass {
    static [object] ShowRunspaceId($val) {
        return [PSCustomObject]@{
            ThreadId   = [Threading.Thread]::CurrentThread.ManagedThreadId
            RunspaceId = [runspace]::DefaultRunspace.Id
        }
    }
}

$unsafe = [UnsafeClass]::new()

while ($true) {
    1..10 | ForEach-Object -Parallel {
        Start-Sleep -ms 100
        ($using:unsafe)::ShowRunspaceId($_)
    }
}

Catatan

Contoh ini berjalan dalam perulangan tak terbatas. Masukkan Ctrl+C untuk menghentikan eksekusi.

Metode ShowRunspaceId() [SafeClass] melaporkan utas dan id Runspace yang berbeda.

# Class definition with NoRunspaceAffinity attribute
[NoRunspaceAffinity()]
class SafeClass {
    static [object] ShowRunspaceId($val) {
        return [PSCustomObject]@{
            ThreadId   = [Threading.Thread]::CurrentThread.ManagedThreadId
            RunspaceId = [runspace]::DefaultRunspace.Id
        }
    }
}

$safe = [SafeClass]::new()

while ($true) {
    1..10 | ForEach-Object -Parallel {
        Start-Sleep -ms 100
        ($using:safe)::ShowRunspaceId($_)
    }
}

Catatan

Contoh ini berjalan dalam perulangan tak terbatas. Masukkan Ctrl+C untuk menghentikan eksekusi.

Properti kelas

Properti adalah variabel yang dideklarasikan dalam cakupan kelas. Properti dapat berupa jenis bawaan atau instans kelas lain. Kelas dapat memiliki nol properti atau lebih. Kelas tidak memiliki jumlah properti maksimum.

Untuk informasi selengkapnya, lihat about_Classes_Properties.

Metode kelas

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.

Untuk informasi selengkapnya, lihat about_Classes_Methods.

Konstruktor kelas

Konstruktor memungkinkan Anda mengatur nilai default dan memvalidasi logika objek saat membuat instans kelas. Konstruktor memiliki nama yang sama dengan kelas . Konstruktor mungkin memiliki parameter, untuk menginisialisasi anggota data objek baru.

Untuk informasi selengkapnya, lihat about_Classes_Constructors.

Kata kunci tersembunyi

Kata hidden kunci menyembunyikan anggota kelas. Anggota masih dapat diakses oleh pengguna dan tersedia di semua cakupan tempat objek tersedia. Anggota tersembunyi disembunyikan dari Get-Member cmdlet dan tidak dapat ditampilkan menggunakan penyelesaian tab atau IntelliSense di luar definisi kelas.

Kata hidden kunci hanya berlaku untuk anggota kelas, bukan kelas itu sendiri.

Anggota kelas tersembunyi adalah:

  • Tidak disertakan dalam output default untuk kelas .
  • Tidak termasuk dalam daftar anggota kelas yang Get-Member dikembalikan oleh cmdlet. Untuk menampilkan anggota tersembunyi dengan Get-Member, gunakan parameter Paksa .
  • Tidak ditampilkan dalam penyelesaian tab atau IntelliSense kecuali penyelesaian terjadi di kelas yang menentukan anggota tersembunyi.
  • Anggota publik kelas. Mereka dapat diakses, diwariskan, dan dimodifikasi. Menyembunyikan anggota tidak membuatnya pribadi. Ini hanya menyembunyikan anggota seperti yang dijelaskan di poin sebelumnya.

Catatan

Ketika Anda menyembunyikan kelebihan beban untuk metode , metode tersebut dihapus dari IntelliSense, hasil penyelesaian, dan output default untuk Get-Member. Saat Anda menyembunyikan konstruktor apa pun, new() opsi dihapus dari IntelliSense dan hasil penyelesaian.

Untuk informasi selengkapnya tentang kata kunci, lihat about_Hidden. Untuk informasi selengkapnya tentang properti tersembunyi, lihat about_Classes_Properties. Untuk informasi selengkapnya tentang metode tersembunyi, lihat about_Classes_Methods. Untuk informasi selengkapnya tentang konstruktor tersembunyi, lihat about_Classes_Constructors.

Kata kunci statis

Kata static kunci mendefinisikan properti atau metode yang ada di kelas dan tidak memerlukan instans.

Properti statis selalu tersedia, independen dari instansiasi kelas. Properti statis dibagikan di semua instans kelas. Metode statis selalu tersedia. Semua properti statis hidup untuk seluruh rentang sesi.

Kata static kunci hanya berlaku untuk anggota kelas, bukan kelas itu sendiri.

Untuk informasi selengkapnya tentang properti statis, lihat about_Classes_Properties. Untuk informasi selengkapnya tentang metode statis, lihat about_Classes_Methods. Untuk informasi selengkapnya tentang konstruktor statis, lihat about_Classes_Constructors.

Warisan dalam kelas PowerShell

Anda dapat memperluas kelas dengan membuat kelas baru yang berasal dari kelas yang ada. Kelas turunan mewarisi properti dan metode kelas dasar. Anda dapat menambahkan atau mengambil alih anggota kelas dasar sesuai kebutuhan.

PowerShell tidak mendukung beberapa pewarisan. Kelas tidak dapat mewarisi langsung dari lebih dari satu kelas.

Kelas juga dapat mewarisi dari antarmuka, yang menentukan kontrak. Kelas yang mewarisi dari antarmuka harus mengimplementasikan kontrak tersebut. Ketika itu terjadi, kelas dapat digunakan seperti kelas lain yang mengimplementasikan antarmuka tersebut.

Untuk informasi selengkapnya tentang mendapatkan kelas yang mewarisi dari kelas dasar atau mengimplementasikan antarmuka, lihat about_Classes_Inheritance.

Atribut NoRunspaceAffinity

Runspace adalah lingkungan operasi untuk perintah yang dipanggil oleh PowerShell. Lingkungan ini mencakup perintah dan data yang saat ini ada, dan batasan bahasa apa pun yang saat ini berlaku.

Secara default, kelas PowerShell berafiliasi dengan Runspace tempat kelas dibuat. Menggunakan kelas ForEach-Object -Parallel PowerShell tidak aman. Pemanggilan metode pada kelas dinamai kembali ke Runspace tempatnya dibuat, yang dapat merusak status Runspace atau menyebabkan kebuntuan.

NoRunspaceAffinity Menambahkan atribut ke definisi kelas memastikan bahwa kelas PowerShell tidak berafiliasi dengan runspace tertentu. Pemanggilan metode, baik instans maupun statis, menggunakan Runspace utas yang sedang berjalan dan status sesi utas saat ini.

Atribut ditambahkan di PowerShell 7.4.

Untuk ilustrasi perbedaan perilaku untuk kelas dengan dan tanpa NoRunspaceAffinity atribut, lihat Contoh 4.

Mengekspor kelas dengan akselerator jenis

Secara default, modul PowerShell tidak secara otomatis mengekspor kelas dan enumerasi yang ditentukan di PowerShell. Jenis kustom tidak tersedia di luar modul tanpa memanggil using module pernyataan.

Namun, jika modul menambahkan akselerator jenis, akselerator jenis tersebut segera tersedia dalam sesi setelah pengguna mengimpor modul.

Catatan

Menambahkan akselerator jenis ke sesi menggunakan API internal (bukan publik). Menggunakan API ini dapat menyebabkan konflik. Pola yang dijelaskan di bawah ini melemparkan kesalahan jika akselerator jenis dengan nama yang sama sudah ada saat Anda mengimpor modul. Ini juga menghapus jenis akselerator saat Anda menghapus modul dari sesi.

Pola ini memastikan bahwa jenis tersedia dalam sesi. Ini tidak memengaruhi IntelliSense atau penyelesaian saat menulis file skrip di Visual Studio Code. Untuk mendapatkan saran IntelliSense dan penyelesaian untuk jenis kustom di Visual Studio Code, Anda perlu menambahkan using module pernyataan ke bagian atas skrip.

Pola berikut menunjukkan bagaimana Anda dapat mendaftarkan kelas dan enumerasi PowerShell sebagai akselerator jenis dalam modul. Tambahkan cuplikan ke modul skrip akar setelah definisi jenis apa pun. Pastikan $ExportableTypes variabel berisi setiap jenis yang ingin Anda sediakan untuk pengguna saat mengimpor modul. Kode lain tidak memerlukan pengeditan apa pun.

# Define the types to export with type accelerators.
$ExportableTypes =@(
    [DefinedTypeName]
)
# Get the internal TypeAccelerators class to use its static methods.
$TypeAcceleratorsClass = [psobject].Assembly.GetType(
    'System.Management.Automation.TypeAccelerators'
)
# Ensure none of the types would clobber an existing type accelerator.
# If a type accelerator with the same name exists, throw an exception.
$ExistingTypeAccelerators = $TypeAcceleratorsClass::Get
foreach ($Type in $ExportableTypes) {
    if ($Type.FullName -in $ExistingTypeAccelerators.Keys) {
        $Message = @(
            "Unable to register type accelerator '$($Type.FullName)'"
            'Accelerator already exists.'
        ) -join ' - '

        throw [System.Management.Automation.ErrorRecord]::new(
            [System.InvalidOperationException]::new($Message),
            'TypeAcceleratorAlreadyExists',
            [System.Management.Automation.ErrorCategory]::InvalidOperation,
            $Type.FullName
        )
    }
}
# Add type accelerators for every exportable type.
foreach ($Type in $ExportableTypes) {
    $TypeAcceleratorsClass::Add($Type.FullName, $Type)
}
# Remove type accelerators when the module is removed.
$MyInvocation.MyCommand.ScriptBlock.Module.OnRemove = {
    foreach($Type in $ExportableTypes) {
        $TypeAcceleratorsClass::Remove($Type.FullName)
    }
}.GetNewClosure()

Saat pengguna mengimpor modul, jenis apa pun yang ditambahkan ke akselerator jenis untuk sesi segera tersedia untuk IntelliSense dan penyelesaian. Ketika modul dihapus, begitu juga akselerator jenis.

Mengimpor kelas secara manual dari modul PowerShell

Import-Module#requires dan pernyataan hanya mengimpor fungsi modul, alias, dan variabel, seperti yang didefinisikan oleh modul. Kelas tidak diimpor.

Jika modul mendefinisikan kelas dan enumerasi tetapi tidak menambahkan akselerator jenis untuk jenis tersebut, gunakan using module pernyataan untuk mengimpornya.

Pernyataan mengimpor using module kelas dan enumerasi dari modul akar (ModuleToProcess) modul skrip atau modul biner. Ini tidak secara konsisten mengimpor kelas yang ditentukan dalam modul atau kelas berlapis yang ditentukan dalam skrip yang bersumber titik ke dalam modul akar. Tentukan kelas yang ingin Anda sediakan untuk pengguna di luar modul langsung di modul akar.

Untuk informasi selengkapnya tentang pernyataan tersebut using , lihat about_Using.

Memuat kode yang baru diubah selama pengembangan

Selama pengembangan modul skrip, umumnya untuk membuat perubahan pada kode lalu memuat versi baru modul menggunakan Import-Module dengan parameter Force . Memuat ulang modul hanya berfungsi untuk perubahan pada fungsi dalam modul akar. Import-Module tidak memuat ulang modul berlapis apa pun. Selain itu, tidak ada cara untuk memuat kelas yang diperbarui.

Untuk memastikan bahwa Anda menjalankan versi terbaru, Anda harus memulai sesi baru. Kelas dan enumerasi yang ditentukan di PowerShell dan diimpor dengan using pernyataan tidak dapat dibongkar.

Praktik pengembangan umum lainnya adalah memisahkan kode Anda ke dalam file yang berbeda. Jika Anda memiliki fungsi dalam satu file yang menggunakan kelas yang ditentukan dalam modul lain, Anda harus menggunakan using module pernyataan untuk memastikan bahwa fungsi memiliki definisi kelas yang diperlukan.

Jenis PSReference tidak didukung dengan anggota kelas

Akselerator [ref] jenis dipersingkat untuk kelas PSReference . Menggunakan [ref] untuk mengetik-cast anggota kelas gagal diam-diam. API yang menggunakan [ref] parameter tidak dapat digunakan dengan anggota kelas. Kelas PSReference dirancang untuk mendukung objek COM. Objek COM memiliki kasus di mana Anda perlu meneruskan nilai berdasarkan referensi.

Untuk informasi selengkapnya, lihat Kelas PSReference.

Batasan

Daftar berikut ini mencakup batasan untuk menentukan kelas dan solusi PowerShell untuk batasan tersebut, jika ada.

Batasan umum

  • Anggota kelas tidak dapat menggunakan PSReference sebagai jenisnya.

    Penanganan masalah: Tidak ada.

  • Kelas PowerShell tidak dapat dibongkar atau dimuat ulang dalam sesi.

    Solusi sementara: Mulai sesi baru.

  • Kelas PowerShell yang ditentukan dalam modul tidak diimpor secara otomatis.

    Solusi sementara: Tambahkan jenis yang ditentukan ke daftar akselerator jenis dalam modul akar. Ini membuat jenis tersedia pada impor modul.

  • Kata hidden kunci dan static hanya berlaku untuk anggota kelas, bukan definisi kelas.

    Penanganan masalah: Tidak ada.

  • Secara default, kelas PowerShell tidak aman digunakan dalam eksekusi paralel di seluruh runspace. Saat Anda Memanggil metode pada kelas, PowerShell melakukan marshal pada pemanggilan kembali ke Runspace tempat kelas dibuat, yang dapat merusak status Runspace atau menyebabkan kebuntuan.

    Solusi sementara: Tambahkan NoRunspaceAffinity atribut ke deklarasi kelas.

Batasan konstruktor

  • Penautan konstruktor tidak diimplementasikan.

    Solusi sementara: Tentukan metode tersembunyi Init() dan panggil dari dalam konstruktor.

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

    Solusi sementara: Menetapkan ulang parameter dalam isi konstruktor dengan atribut validasi.

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

    Penanganan masalah: Tidak ada.

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

    Penanganan masalah: Tidak ada.

Batasan metode

  • 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.

Batasan properti

  • Properti statis selalu dapat diubah. Kelas PowerShell tidak dapat menentukan properti statis yang tidak dapat diubah.

    Penanganan masalah: Tidak ada.

  • Properti tidak dapat menggunakan atribut ValidateScript , karena argumen atribut properti kelas harus konstanta.

    Solusi sementara: Tentukan kelas yang mewarisi dari jenis ValidateArgumentsAttribute dan gunakan atribut tersebut sebagai gantinya.

  • Properti yang dideklarasikan secara langsung tidak dapat menentukan implementasi getter dan setter kustom.

    Solusi sementara: Tentukan properti tersembunyi dan gunakan Update-TypeData untuk menentukan logika getter dan setter yang terlihat.

  • Properti tidak dapat menggunakan atribut Alias . Atribut hanya berlaku untuk parameter, cmdlet, dan fungsi.

    Solusi sementara: Gunakan Update-TypeData cmdlet untuk menentukan alias di konstruktor kelas.

  • Saat kelas PowerShell dikonversi ke JSON dengan ConvertTo-Json cmdlet, JSON output menyertakan semua properti tersembunyi dan nilainya.

    Solusi sementara: Tidak ada

Batasan warisan

  • PowerShell tidak mendukung pendefinisian antarmuka dalam kode skrip.

    Solusi sementara: Tentukan antarmuka di C# dan referensikan rakitan yang menentukan antarmuka.

  • Kelas PowerShell hanya dapat mewarisi dari satu kelas dasar.

    Solusi sementara: Pewarisan kelas bersifat transitif. Kelas turunan dapat mewarisi dari kelas turunan lain untuk mendapatkan properti dan metode kelas dasar.

  • Saat mewarisi dari kelas atau antarmuka generik, parameter jenis untuk generik harus sudah ditentukan. Kelas tidak dapat mendefinisikan dirinya sebagai parameter jenis untuk kelas atau antarmuka.

    Solusi sementara: Untuk memperoleh dari kelas atau antarmuka dasar generik, tentukan jenis kustom dalam file yang berbeda .psm1 dan gunakan using module pernyataan untuk memuat jenis. Tidak ada solusi untuk jenis kustom untuk menggunakan dirinya sendiri sebagai parameter jenis saat mewarisi dari generik.

Lihat juga