ja-JP/about_Ref.help.txt

TOPIC
    about_Ref

簡単な説明
    参照型変数を作成して使用する方法について説明します。

詳細な説明
    変数は、参照渡し (by reference) または値渡し (by value) で関数に
    渡すことができます。変数を値渡しすると、データのコピーが渡されます。
    変数を参照渡しすると、元の値への参照が渡されます。これにより、関数は
    渡された変数の値を変更できます。参照型は [ref] を使って作成します。
    [ref] は [System.Management.Automation.PSReference] 型の型
    アクセラレーターです。

    [ref] の主な目的は、ref、out、または in としてマークされた .NET の
    メソッドパラメーターに、PowerShell の変数を参照渡しで渡せるように
    することです。[ref] 型のパラメーターを受け取る独自の PowerShell 関数
    を定義することもできます。この使い方では、[ref] は変数に適用され、
    得られた [ref] インスタンスを使ってその変数の値を間接的に変更できます。

    次の例では、関数が渡された変数の値を変更します。PowerShell では整数は
    値型なので値渡しされます。そのため、関数のスコープの外では $var の値は
    変更されません。

        Function Test($Data)
        {
            $Data = 3
        }

        $var = 10
        Test -Data $var
        $var

    出力:

        10

    次の例では、Hashtable を含む変数が関数に渡されます。Hashtable は
    オブジェクト型なので、既定では参照渡しで関数に渡されます。

    変数を参照渡しすると、関数はデータを変更でき、その変更は関数の実行後も
    保持されます。

        Function Test($Data)
        {
            $Data.Test = "New Text"
        }

        $var = @{}
        Test -Data $var
        $var

    出力:

        Name Value
        ---- -----
        Test New Text

    関数は、関数のスコープの外でも保持される新しいキーと値のペアを追加
    します。

参照パラメーターを受け取る関数の記述
    渡されるデータの型に関係なく、パラメーターを参照として受け取るように
    関数を記述できます。これにはパラメーターの型を [ref] として指定する
    必要があります。

    参照を使用する場合、データにアクセスするには [ref] 型の Value
    プロパティを使用する必要があります。

        function Test {
            param([ref]$Data)
            $Data.Value = 3
        }

    参照を期待するパラメーターに変数を渡すには、変数を参照として型変換
    する必要があります。

    重要:
        角かっこと丸かっこの両方が必要です。

        $var = 10
        Test -Data ([ref]$var)
        $var

    出力:

        3

.NET メソッドへの参照の受け渡し
    一部の .NET メソッドでは、変数を参照として渡す必要があります。
    メソッドの定義でパラメーターに in、out、または ref キーワードが
    使われている場合、それは参照を期待しています。

        [int] | Get-Member -Static -Name TryParse

    出力:

        Name MemberType Definition
        ---- ---------- ----------
        TryParse Method static bool TryParse(string s, [ref] int result)

    TryParse メソッドは文字列を整数として解析しようとします。メソッドが
    成功すると $true を返し、結果は参照渡しで渡した変数に格納されます。

        PS> $number = 0
        PS> [int]::TryParse("15", ([ref]$number))
        True
        PS> $number
        15

参照とスコープ
    参照を使うと、子スコープ内で親スコープの変数の値を変更できます。

        # 値型の変数を作成する。
        $i = 0
        # 参照型の変数を作成する。
        $iRef = [ref]0
        # スクリプトブロックを呼び出して両方の値の変更を試みる。
        &{$i++;$iRef.Value++}
        # 結果を出力する。
        "`$i = $i;`$iRef = $($iRef.Value)"

    出力:

        $i = 0;$iRef = 1

    参照型の変数だけが変更されました。

汎用のオブジェクトホルダーとしての [ref] の使用
    [ref] を汎用のオブジェクトホルダーとして使用することもできます。
    この使い方では、[ref] は変数ではなく値に適用されます。通常、値は
    数値などの値型のインスタンスです。ほとんどのシナリオでは、代わりに
    通常の変数やパラメーターを使用できます。ただし、この手法は、簡潔さの
    ために明示的な値ホルダーの受け渡しが望ましくない場合や、スクリプト
    ブロックのパラメーター値のように受け渡しが不可能な場合に役立ちます。

    たとえば、スクリプトブロックのパラメーター値を使って、Rename-Item
    コマンドレットの NewName パラメーターの値を計算できます。Rename-Item
    コマンドレットでは、項目をパイプで渡すことができます。このコマンドは、
    パイプライン内の各項目について NewName に渡されたスクリプトブロックを
    実行します。スクリプトブロックは子スコープで実行されます。呼び出し元の
    スコープの変数を直接変更しても役に立たず、このコンテキストでは
    スクリプトブロックに引数を渡すこともできません。

    この例では、NewName パラメーターに渡されたスクリプトブロックが、
    パイプライン内の各項目について $iRef の値をインクリメントします。
    スクリプトブロックは、ファイル名の先頭に数値を追加して新しい名前を
    作成します。

        $iRef = [ref] 0
        Get-ChildItem -File $setPath |
            Rename-Item -NewName { '{0} - {1}' -f $iRef.Value++,$_.Name }

[ref] と [System.Management.Automation.PSReference] の違い
    参照型変数は、[ref] 型アクセラレーターを使うか、
    [System.Management.Automation.PSReference] 型を直接指定して作成
    します。[ref] は [System.Management.Automation.PSReference] の型
    アクセラレーターですが、両者の動作は異なります。

    - [ref] を使って変数を型変換すると、PowerShell は変数の元の
      インスタンスへの参照を含む参照オブジェクトを作成します。
    - [System.Management.Automation.PSReference] を使って変数を型変換
      すると、PowerShell は元のインスタンスへの参照ではなく、変数の
      コピーを含む参照オブジェクトを作成します。

    たとえば、次のスクリプトは変数 $int と 2 つの参照オブジェクトを作成
    します。

        PS> $int = 1
        PS> $aRef = [ref] $int
        PS> $bRef = [System.Management.Automation.PSReference] $int
        PS> $int
        1
        PS> $aRef, $bRef

        Value
        -----
            1
            1

    この時点では、両方の参照オブジェクトは $int と同じ値を持ちます。
    参照オブジェクトに異なる値を加えると、[ref] で作成された $aRef は
    $int の元のインスタンスへの参照であることがわかります。
    [System.Management.Automation.PSReference] で作成された $bRef は
    変数のコピーです。

        PS> $aRef.Value+=2
        PS> $bRef.Value+=5
        PS> $int
        3
        PS> $aRef, $bRef

        Value
        -----
            3
            6

関連項目
    about_Variables
    about_Environment_Variables
    about_Functions
    about_Script_Blocks
    about_Scopes
    about_Type_Accelerators
    System.Management.Automation.PSReference

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