ja-JP/about_Classes.help.txt

TOPIC
    about_Classes

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

詳細な説明
    PowerShell はバージョン 5.0 以降、クラスやその他のユーザー定義型を
    定義するための正式な構文を備えています。クラスの追加により、開発者や
    IT プロフェッショナルはより幅広いユースケースで PowerShell を活用できる
    ようになりました。

    クラス宣言は、実行時にオブジェクトのインスタンスを作成するために使われる
    設計図です。クラスを定義すると、クラス名がその型の名前になります。たとえば
    Device という名前のクラスを宣言し、変数 $dev を Device の新しいインスタンス
    で初期化すると、$dev は Device 型のオブジェクト (インスタンス) になります。
    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>]<convertable-value-type>

        注意:
            [<class-name>]::new() 構文を使うとき、クラス名を囲む角かっこは
            必須です。角かっこは PowerShell に型定義であることを伝えます。
            <convertable-value-type> 構文は、パラメーターを必要としない既定
            のコンストラクターを持つクラスでのみ機能します。


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

        次の例は、既定のコンストラクターが型強制を使って互換性のある値から
        プロパティを割り当てる方法を示します。ここではハッシュテーブルを
        使ってプロパティ値を渡しています。

            $Book1 = [Book] @{
                Title = '1984'
                Author = 'George Orwell'
                Synopsis = ''
                Publisher = 'Secker & Warburg'
                PublishDate = '1949-06-08'
                PageCount = 328
                Tags = @('Dystopian', 'Political Fiction', 'Social Science Fiction')
            }
            $Book1

        ハッシュテーブルのキーと値のペアがインスタンスのプロパティに割り当て
        られます。ハッシュテーブルのキーが有効なプロパティ名でない場合、
        インスタンス化は失敗します。

    例 3 - インスタンスメンバーを持つクラス
        この例では、複数のプロパティ、コンストラクター、メソッドを持つ 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))"
                }
            }

    例 4 - 静的メンバーを持つクラス
        この例の BookList クラスは、前の例の Book クラスを基にしています。
        BookList クラス自体を static にすることはできませんが、この実装では
        Books 静的プロパティと、そのプロパティを管理する一連の静的メソッド
        だけを定義します。

    例 5 - Runspace アフィニティありとなしのクラス定義
        既定の動作 (Runspace アフィニティあり) では、[UnsafeClass] の
        ShowRunspaceId() メソッドは異なるスレッド ID を報告しますが、同じ
        Runspace 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
                    }
                }
            }

        NoRunspaceAffinity 属性を持つ [SafeClass] の ShowRunspaceId()
        メソッドは、異なるスレッド ID と Runspace ID を報告します。

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

クラスのプロパティ
    プロパティはクラスのスコープで宣言される変数です。プロパティには任意の
    組み込み型、または別のクラスのインスタンスを使えます。クラスは 0 個以上の
    プロパティを持てます。プロパティ数の上限はありません。詳細は
    about_Classes_Properties を参照してください。

クラスのメソッド
    メソッドはクラスが実行できる動作を定義します。メソッドは入力データを
    指定するパラメーターを取れます。メソッドは常に出力型を定義します。メソッド
    が出力を返さない場合は、出力型を Void にする必要があります。出力型を明示的
    に定義しない場合、メソッドの出力型は Void になります。詳細は
    about_Classes_Methods を参照してください。

クラスのコンストラクター
    コンストラクターを使うと、クラスのインスタンスを作成する瞬間に既定値を
    設定し、オブジェクトのロジックを検証できます。コンストラクターはクラスと
    同じ名前を持ちます。新しいオブジェクトのデータメンバーを初期化するため、
    コンストラクターはパラメーターを持つことがあります。詳細は
    about_Classes_Constructors を参照してください。

hidden キーワード
    hidden キーワードはクラスメンバーを隠します。そのメンバーは依然として
    ユーザーがアクセス可能で、オブジェクトが利用可能なすべてのスコープで
    利用できます。隠されたメンバーは Get-Member コマンドレットからは隠され、
    クラス定義の外ではタブ補完や IntelliSense で表示できません。

    hidden キーワードはクラス自体ではなくクラスメンバーにのみ適用されます。

    隠されたクラスメンバーは次のとおりです。

        - クラスの既定の出力に含まれません。
        - Get-Member コマンドレットが返すクラスメンバーの一覧に含まれません。
          Get-Member で隠されたメンバーを表示するには Force パラメーターを
          使います。
        - 隠されたメンバーを定義するクラス内で補完が行われる場合を除き、
          タブ補完や IntelliSense に表示されません。
        - クラスのパブリックメンバーです。アクセス、継承、変更が可能です。
          メンバーを隠してもプライベートにはなりません。

    詳細は about_Hidden を参照してください。

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

    静的プロパティはクラスのインスタンス化とは無関係に常に利用可能です。
    静的プロパティはクラスのすべてのインスタンス間で共有されます。静的メソッド
    は常に利用可能です。すべての静的プロパティはセッション全体にわたって存在
    します。

    static キーワードはクラス自体ではなくクラスメンバーにのみ適用されます。

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

    PowerShell は多重継承をサポートしません。クラスが複数のクラスから直接
    継承することはできません。

    クラスは、契約を定義するインターフェイスから継承することもできます。
    インターフェイスから継承するクラスは、その契約を実装する必要があります。
    詳細は about_Classes_Inheritance を参照してください。

NoRunspaceAffinity 属性
    runspace は、PowerShell によって呼び出されるコマンドの実行環境です。
    既定では、PowerShell クラスは作成された Runspace に関連付けられます。
    PowerShell クラスを ForEach-Object -Parallel で使うのは安全ではありません。
    クラスのメソッド呼び出しは作成された Runspace にマーシャリングされ、
    Runspace の状態を破損させたりデッドロックを引き起こしたりする可能性が
    あります。

    クラス定義に NoRunspaceAffinity 属性を追加すると、PowerShell クラスが
    特定の runspace に関連付けられないようになります。インスタンスメソッドと
    静的メソッドの両方の呼び出しが、実行中のスレッドの Runspace とそのスレッド
    の現在のセッション状態を使うようになります。この属性は PowerShell 7.4 で
    追加されました。

型アクセラレーターによるクラスのエクスポート
    既定では、PowerShell モジュールは PowerShell で定義されたクラスや列挙型を
    自動的にエクスポートしません。これらのカスタム型は、using module
    ステートメントを呼び出さない限りモジュールの外では使えません。

    ただし、モジュールが型アクセラレーターを追加すると、その型アクセラレーター
    はユーザーがモジュールをインポートした直後にセッションで利用可能になります。

PowerShell モジュールからのクラスの手動インポート
    Import-Module と #Requires ステートメントは、モジュールで定義された関数、
    エイリアス、変数だけをインポートします。クラスはインポートされません。

    モジュールがクラスや列挙型を定義していても型アクセラレーターを追加して
    いない場合は、using module ステートメントを使ってインポートします。詳細は
    about_Using を参照してください。

開発中の変更コードの読み込み
    スクリプトモジュールの開発中は、コードを変更してから Force パラメーター
    付きの Import-Module で新しいバージョンのモジュールを読み込むのが一般的
    です。モジュールの再読み込みはルートモジュールの関数への変更に対してのみ
    機能します。最新バージョンを実行していることを確実にするには、新しい
    セッションを開始する必要があります。

PSReference 型はクラスメンバーではサポートされません
    [ref] 型アクセラレーターは PSReference クラスの省略表記です。[ref] を
    使ってクラスメンバーを型キャストすると、何も通知されずに失敗します。
    [ref] パラメーターを使う API はクラスメンバーでは使えません。詳細は
    PSReference Class を参照してください。

制限事項
    一般的な制限事項
        - クラスメンバーは型として PSReference を使えません。回避策: なし。
        - PowerShell クラスはセッション内でアンロードや再読み込みができません。
          回避策: 新しいセッションを開始します。
        - モジュールで定義された PowerShell クラスは自動的にインポートされ
          ません。回避策: 定義した型をルートモジュールの型アクセラレーターの
          一覧に追加します。
        - hidden および static キーワードはクラス定義ではなくクラスメンバーに
          のみ適用されます。回避策: なし。
        - 既定では、PowerShell クラスは runspace をまたぐ並列実行で使うのは
          安全ではありません。回避策: クラス宣言に NoRunspaceAffinity 属性を
          追加します。

    コンストラクターの制限事項
        - コンストラクターチェーンは実装されていません。回避策: 隠された
          Init() メソッドを定義し、コンストラクターから呼び出します。
        - コンストラクターのパラメーターは、検証属性を含むいかなる属性も
          使えません。回避策: コンストラクター本体でパラメーターを検証属性
          付きで再代入します。
        - コンストラクターのパラメーターは既定値を定義できません。パラメーター
          は常に必須です。回避策: なし。

    メソッドの制限事項
        - メソッドのパラメーターは、検証属性を含むいかなる属性も使えません。
          回避策: メソッド本体で再代入するか、Update-TypeData コマンドレット
          で静的コンストラクター内にメソッドを定義します。
        - メソッドのパラメーターは既定値を定義できません。回避策:
          Update-TypeData コマンドレットでメソッドを定義します。
        - メソッドは隠されていても常にパブリックです。

    プロパティの制限事項
        - 静的プロパティは常に変更可能です。PowerShell クラスは不変の静的
          プロパティを定義できません。回避策: なし。
        - プロパティは ValidateScript 属性を使えません。回避策:
          ValidateArgumentsAttribute 型を継承するクラスを定義して使います。
        - 直接宣言されたプロパティはカスタムのゲッターやセッターを定義できま
          せん。回避策: 隠されたプロパティを定義し、Update-TypeData を使います。

    継承の制限事項
        - PowerShell はスクリプトコードでのインターフェイス定義をサポートしま
          せん。回避策: C# でインターフェイスを定義し、そのアセンブリを参照
          します。
        - PowerShell クラスは 1 つの基底クラスからしか継承できません。回避策:
          クラスの継承は推移的です。派生クラスを別の派生クラスから継承します。

関連項目
    about_Classes_Constructors
    about_Classes_Inheritance
    about_Classes_Methods
    about_Classes_Properties
    about_Enum
    about_Hidden
    about_Language_Keywords
    about_Methods
    about_Using

----
原文: PowerShell-Docs (CC BY 4.0) の翻訳 / PSHelpJaJP