about_Classes

簡単な説明

クラスを使用して独自のカスタム型を作成する方法について説明します。

詳細な説明

バージョン 5.0 以降、PowerShell には、クラスやその他のユーザー定義型を定義するための正式な構文があります。 クラスを追加することで、開発者や IT プロフェッショナルは、より広範なユース ケースに PowerShell を採用できます。

クラス宣言は、実行時にオブジェクトのインスタンスを作成するために使用されるブループリントです。 クラスを定義する場合、クラス名は型の名前です。 たとえば、Device という名前のクラスを宣言し、Device の新しいインスタンスに$dev変数を初期化する場合、$devDevice 型のオブジェクトまたはインスタンスです。 Deviceの各インスタンスは、そのプロパティに異なる値を持つことができます。

サポートされるシナリオ

  • クラス、プロパティ、メソッド、継承などのオブジェクト指向プログラミング セマンティクスを使用して、PowerShell でカスタム型を定義します。
  • PowerShell 言語を使用して、DSC リソースとそれに関連付けられている型を定義します。
  • 変数、パラメーター、およびカスタム型定義を装飾するカスタム属性を定義します。
  • 型名でキャッチできるカスタム例外を定義します。

構文

定義の構文

クラス定義では、次の構文を使用します。

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

インスタンス化の構文

クラスのインスタンスをインスタンス化するには、次のいずれかの構文を使用します。

[$<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>]}

Note

[<class-name>]::new()構文を使用する場合は、クラス名を角かっこで囲む必要があります。 角かっこは、PowerShell の型定義を示します。

ハッシュテーブル構文は、パラメーターを予期しない既定のコンストラクターを持つクラスでのみ機能します。 既定のコンストラクターを使用してクラスのインスタンスを作成し、インスタンス プロパティにキーと値のペアを割り当てます。 ハッシュテーブル内のキーが有効なプロパティ名でない場合、PowerShell はエラーを発生させます。

例 1 - 最小定義

この例では、使用可能なクラスを作成するために必要な最小限の構文を示します。

class Device {
    [string]$Brand
}

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

例 2 - インスタンス メンバーを持つクラス

この例では、いくつかのプロパティ、コンストラクター、およびメソッドを持つ Book クラスを定義します。 定義されているすべてのメンバーは、静的メンバーではなく、 メンバーです。 プロパティとメソッドには、クラスの作成されたインスタンスを介してのみアクセスできます。

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

次のスニペットは、クラスのインスタンスを作成し、その動作を示しています。 この例では、 Book クラスのインスタンスを作成した後、 GetReadingTime() メソッドと GetPublishedAge() メソッドを使用して書籍に関するメッセージを書き込みます。

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

例 3 - 静的メンバーを持つクラス

この例の BookList クラスは、例 2 の Book クラスに基づいています。 BookList クラスを静的としてマークすることはできませんが、実装では、 Books 静的プロパティとそのプロパティを管理するための静的メソッドのセットのみが定義されます。

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

BookListが定義されたので、前の例の書籍をリストに追加できます。

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

次のスニペットは、クラスの静的メソッドを呼び出します。

[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

例 4 - Runspace アフィニティの有無に関するクラス定義

[UnsafeClass]ShowRunspaceId()メソッドは、異なるスレッド ID を報告しますが、実行空間 ID は同じです。 最終的に、セッションの状態が破損し、 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($_)
    }
}

Note

この例は無限ループで実行されます。 Ctrl+C を入力して実行を停止します。

[SafeClass]ShowRunspaceId()メソッドは、さまざまなスレッド ID と実行空間 ID を報告します。

# 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($_)
    }
}

Note

この例は無限ループで実行されます。 Ctrl+C を入力して実行を停止します。

クラスのプロパティ

プロパティは、クラス スコープで宣言された変数です。 プロパティには、任意の組み込み型または別のクラスのインスタンスを指定できます。 クラスには、0 個以上のプロパティを含めることができます。 クラスには最大プロパティ数がありません。

詳細については、 about_Classes_Propertiesを参照してください。

クラス メソッド

メソッドは、クラスが実行できるアクションを定義します。 メソッドは、入力データを指定するパラメーターを受け取ることができます。 メソッドは常に出力の種類を定義します。 メソッドが出力を返さない場合は、 Void 出力型が必要です。 メソッドが出力型を明示的に定義しない場合、メソッドの出力型は Void

詳細については、「 about_Classes_Methods」を参照してください。

クラス コンストラクター

コンストラクターを使用すると、クラスのインスタンスを作成するときに、既定値を設定し、オブジェクト ロジックを検証できます。 コンストラクターの名前はクラスと同じです。 コンストラクターには、新しいオブジェクトのデータ メンバーを初期化するためのパラメーターが含まれる場合があります。

詳細については、「 about_Classes_Constructors」を参照してください。

Hidden キーワード

hidden キーワードは、クラス メンバーを非表示にします。 メンバーは引き続きユーザーがアクセスでき、オブジェクトが使用可能なすべてのスコープで使用できます。 非表示のメンバーは、 Get-Member コマンドレットから非表示になり、クラス定義の外部でタブ補完または IntelliSense を使用して表示することはできません。

hidden キーワードはクラス メンバーにのみ適用され、クラス自体には適用されません。

非表示のクラス メンバーは次のとおりです。

  • クラスの既定の出力には含まれません。
  • Get-Member コマンドレットによって返されるクラス メンバーの一覧には含まれません。 非表示のメンバーを Get-Memberと共に表示するには、 Force パラメーターを使用します。
  • 非表示のメンバーを定義するクラスで入力候補が発生しない限り、タブ補完または IntelliSense には表示されません。
  • クラスのパブリック メンバー。 アクセス、継承、および変更が可能です。 メンバーを非表示にしても、プライベートにはなりません。 前のポイントで説明したように、メンバーのみが非表示になります。

Note

メソッドのオーバーロードを非表示にすると、そのメソッドは IntelliSense、完了結果、および Get-Memberの既定の出力から削除されます。 コンストラクターを非表示にすると、 new() オプションが IntelliSense と入力候補の結果から削除されます。

キーワードの詳細については、 about_Hiddenを参照してください。 非表示のプロパティの詳細については、「 about_Classes_Properties」を参照してください。 非表示のメソッドの詳細については、「 about_Classes_Methods」を参照してください。 非表示のコンストラクターの詳細については、「 about_Classes_Constructors」を参照してください。

Static キーワード

static キーワードは、クラスに存在し、インスタンスを必要としないプロパティまたはメソッドを定義します。

クラスのインスタンス化に関係なく、静的プロパティは常に使用できます。 静的プロパティは、クラスのすべてのインスタンスで共有されます。 静的メソッドは常に使用できます。 すべての静的プロパティは、セッションスパン全体に対して有効です。

static キーワードはクラス メンバーにのみ適用され、クラス自体には適用されません。

静的プロパティの詳細については、「 about_Classes_Properties」を参照してください。 静的メソッドの詳細については、「 about_Classes_Methods」を参照してください。 静的コンストラクターの詳細については、「 about_Classes_Constructors」を参照してください。

PowerShell クラスでの継承

既存のクラスから派生する新しいクラスを作成することで、クラスを拡張できます。 派生クラスは、基底クラスのプロパティとメソッドを継承します。 必要に応じて、基底クラスのメンバーを追加またはオーバーライドできます。

PowerShell では、複数の継承はサポートされていません。 クラスは、複数のクラスから直接継承することはできません。

クラスは、コントラクトを定義するインターフェイスから継承することもできます。 インターフェイスから継承するクラスは、そのコントラクトを実装する必要があります。 その場合、クラスは、そのインターフェイスを実装する他のクラスと同様に使用できます。

基底クラスから継承するクラスまたはインターフェイスを実装するクラスの派生の詳細については、 about_Classes_Inheritanceを参照してください。

NoRunspaceAffinity 属性

実行空間は、PowerShell によって呼び出されるコマンドの動作環境です。 この環境には、現在存在するコマンドとデータ、および現在適用されている言語制限が含まれます。

既定では、PowerShell クラスは、作成された Runspace に関連付けられます。 ForEach-Object -Parallelで PowerShell クラスを使用することは安全ではありません。 クラスのメソッド呼び出しは、作成された Runspace にマーシャリングされ、 Runspace の状態が破損したり、デッドロックが発生したりする可能性があります。

クラス定義に NoRunspaceAffinity 属性を追加すると、PowerShell クラスが特定の実行空間に関連付けられません。 インスタンスと静的の両方のメソッド呼び出しでは、実行中のスレッドの Runspace とスレッドの現在のセッション状態を使用します。

この属性は PowerShell 7.4 で追加されました。

NoRunspaceAffinity属性の有無に関するクラスの動作の違いの図については、Example 4を参照してください。

型アクセラレータを使用したクラスのエクスポート

既定では、PowerShell モジュールは、PowerShell で定義されているクラスと列挙型を自動的にエクスポートしません。 カスタム型は、 using module ステートメントを呼び出さずにモジュールの外部では使用できません。

ただし、モジュールが型アクセラレータを追加した場合、ユーザーがモジュールをインポートした後、それらの型アクセラレータはすぐにセッションで使用できます。

Note

型アクセラレータをセッションに追加するには、内部 (パブリックではない) API を使用します。 この API を使用すると、競合が発生する可能性があります。 モジュールのインポート時に同じ名前の型アクセラレータが既に存在する場合、次に示すパターンではエラーがスローされます。 また、セッションからモジュールを削除すると、型アクセラレータも削除されます。

このパターンにより、セッションで型を使用できるようになります。 VS Code でスクリプト ファイルを作成する場合、IntelliSense や入力候補には影響しません。 VS Code でカスタム型の IntelliSense と入力候補を取得するには、スクリプトの先頭に using module ステートメントを追加する必要があります。

次のパターンは、PowerShell クラスと列挙型をモジュールの型アクセラレータとして登録する方法を示しています。 任意の型定義の後に、ルート スクリプト モジュールにスニペットを追加します。 $ExportableTypes変数に、ユーザーがモジュールをインポートするときに使用できるようにする各型が含まれていることを確認します。 他のコードでは、編集は必要ありません。

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

ユーザーがモジュールをインポートすると、セッションの型アクセラレータに追加された型は、IntelliSense と完了にすぐに使用できます。 モジュールが削除されると、型アクセラレータも削除されます。

PowerShell モジュールからクラスを手動でインポートする

Import-Module および #requires ステートメントは、モジュールによって定義されているモジュール関数、エイリアス、変数のみをインポートします。 クラスはインポートされません。

モジュールがクラスと列挙型を定義しているが、それらの型に型アクセラレータを追加しない場合は、 using module ステートメントを使用してそれらをインポートします。

using module ステートメントは、スクリプト モジュールまたはバイナリ モジュールのルート モジュール (ModuleToProcess) からクラスと列挙型をインポートします。 入れ子になったモジュールで定義されているクラスや、ルート モジュールにドット ソース化されたスクリプトで定義されているクラスは、一貫してインポートされません。 ルート モジュール内のモジュール外のユーザーが直接使用できるようにするクラスを定義します。

using ステートメントの詳細については、about_Usingを参照してください。

開発中に新しく変更されたコードを読み込む

スクリプト モジュールの開発中は、コードを変更してから、Force パラメーターを使用してImport-Moduleを使用して新しいバージョンのモジュールを読み込むのが一般的です。 モジュールの再読み込みは、ルート モジュール内の関数に対する変更に対してのみ機能します。 Import-Module では、入れ子になったモジュールは再読み込みされません。 また、更新されたクラスを読み込む方法はありません。

最新バージョンを確実に実行するには、新しいセッションを開始する必要があります。 PowerShell で定義され、 using ステートメントでインポートされたクラスと列挙型はアンロードできません。

もう 1 つの一般的な開発方法は、コードを異なるファイルに分割することです。 別のモジュールで定義されたクラスを使用する 1 つのファイルに関数がある場合は、 using module ステートメントを使用して、関数に必要なクラス定義があることを確認する必要があります。

PSReference 型は、クラス メンバーではサポートされていません

[ref]型アクセラレータは、PSReference クラスの短縮形です。 [ref]を使用してクラス メンバーを型キャストすると、サイレント モードで失敗します。 [ref] パラメーターを使用する API は、クラス メンバーでは使用できません。 PSReference クラスは、COM オブジェクトをサポートするように設計されています。 COM オブジェクトには、値を参照渡しする必要がある場合があります。

詳細については、「 PSReference クラスを参照してください。

制限事項

次の一覧には、PowerShell クラスを定義するための制限事項と、それらの制限がある場合の回避策が含まれます。

一般的な制限事項

  • クラス メンバーは、型として PSReference を使用できません。

    回避策: なし。

  • PowerShell クラスをセッションでアンロードまたは再読み込みすることはできません。

    回避策: 新しいセッションを開始します。

  • モジュールで定義されている PowerShell クラスは自動的にはインポートされません。

    回避策: ルート モジュールの型アクセラレータの一覧に定義済みの型を追加します。 これにより、モジュールのインポート時に型を使用できるようになります。

  • hiddenキーワードとstatic キーワードは、クラス定義ではなく、クラス メンバーにのみ適用されます。

    回避策: なし。

  • 既定では、PowerShell クラスは、実行空間間で並列実行で使用しても安全ではありません。 クラスでメソッドを呼び出すと、PowerShell は呼び出しを Runspace クラスが作成された場所にマーシャリングし直します。これにより、 Runspace の状態が破損したり、デッドロックが発生したりする可能性があります。

    回避策: NoRunspaceAffinity 属性をクラス宣言に追加します。

コンストラクターの制限事項

  • コンストラクターのチェーンは実装されていません。

    回避策: 非表示の Init() メソッドを定義し、コンストラクター内から呼び出します。

  • コンストラクター パラメーターでは、検証属性を含む属性を使用できません。

    回避策: コンストラクター本体のパラメーターを検証属性で再割り当てします。

  • コンストラクター パラメーターでは既定値を定義できません。 パラメーターは常に必須です。

    回避策: なし。

  • コンストラクターのオーバーロードが非表示の場合、コンストラクターのすべてのオーバーロードも非表示として扱われます。

    回避策: なし。

メソッドの制限事項

  • メソッド パラメーターでは、検証属性を含む属性を使用できません。

    回避策: 検証属性を使用してメソッド本体のパラメーターを再割り当てするか、 Update-TypeData コマンドレットを使用して静的コンストラクターでメソッドを定義します。

  • メソッド パラメーターでは既定値を定義できません。 パラメーターは常に必須です。

    回避策: Update-TypeData コマンドレットを使用して、静的コンストラクターでメソッドを定義します。

  • メソッドは、非表示の場合でも常にパブリックです。 これらは、クラスが継承されるときにオーバーライドできます。

    回避策: なし。

  • メソッドのオーバーロードが非表示の場合、そのメソッドのすべてのオーバーロードも非表示として扱われます。

    回避策: なし。

プロパティの制限事項

  • 静的プロパティは常に変更可能です。 PowerShell クラスでは、変更できない静的プロパティを定義できません。

    回避策: なし。

  • クラス プロパティ属性の引数は定数である必要があるため、プロパティは ValidateScript 属性を使用できません。

    回避策: ValidateArgumentsAttribute 型から継承するクラスを定義し、代わりにその属性を使用します。

  • 直接宣言されたプロパティでは、カスタム getter と setter の実装を定義できません。

    回避策: 非表示のプロパティを定義し、 Update-TypeData を使用して、表示されるゲッターとセッターのロジックを定義します。

  • プロパティで Alias 属性を使用することはできません。 この属性は、パラメーター、コマンドレット、関数にのみ適用されます。

    回避策: クラス コンストラクターでエイリアスを定義するには、 Update-TypeData コマンドレットを使用します。

  • ConvertTo-Json コマンドレットを使用して PowerShell クラスを JSON に変換すると、出力 JSON にはすべての非表示プロパティとその値が含まれます。

    回避策: なし

継承の制限事項

  • PowerShell では、スクリプト コードでのインターフェイスの定義はサポートされていません。

    回避策: C# でインターフェイスを定義し、インターフェイスを定義するアセンブリを参照します。

  • PowerShell クラスは、1 つの基本クラスからのみ継承できます。

    回避策: クラスの継承は推移的です。 派生クラスは、別の派生クラスから継承して、基底クラスのプロパティとメソッドを取得できます。

  • ジェネリック クラスまたはインターフェイスから継承する場合は、ジェネリックの型パラメーターが既に定義されている必要があります。 クラス自体をクラスまたはインターフェイスの型パラメーターとして定義することはできません。

    回避策: ジェネリック 基底クラスまたはインターフェイスから派生するには、別の .psm1 ファイルでカスタム型を定義し、 using module ステートメントを使用して型を読み込みます。 ジェネリックから継承するときに、カスタム型が型パラメーターとしてそれ自体を使用する回避策はありません。

関連項目