次の方法で共有


about_Ref

簡単な説明

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

詳細な説明

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

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

次の例では、関数は渡された変数の値を変更します。 PowerShell では、整数は値型であるため、値によって渡されます。 したがって、 $var の値は、関数の範囲外で変更されません。

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

$var = 10
Test -Data $var
$var
10

次の例では、 Hashtable を含む変数が関数に渡されます。 はオブジェクト型であるため、既定では参照によって関数 に渡されます。

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

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

$var = @{}
Test -Data $var
$var
Name                           Value
----                           -----
Test                           New Text

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

参照パラメーターを受け取る関数の記述

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

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

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

参照を必要とするパラメーターに変数を渡すには、変数を参照として型キャストする必要があります。

重要

角かっことかっこはどちらも必須です。

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

.NET メソッドへの参照の渡し

一部の .NET メソッドでは、変数を参照として渡す必要があります。 メソッドの定義でパラメーターのキーワード inout、または 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

参照とスコープ

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

# Create a value type variable.
$i = 0
# Create a reference type variable.
$iRef = [ref]0
# Invoke a scriptblock to attempt to change both values.
&{$i++;$iRef.Value++}
# Output the results.
"`$i = $i;`$iRef = $($iRef.Value)"
$i = 0;$iRef = 1

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

汎用オブジェクトホルダーとして [ref] を使用する

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

たとえば、スクリプトブロックのパラメーター値を使用して、 コマンドレットの Rename-Item パラメーターの値を計算できます。 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 によって作成されます。

たとえば、次のスクリプトは変数 $x と 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と同じです。 参照オブジェクトに異なる値を追加することで、$aRefを使用して作成された [ref]が、$intの元のインスタンスへの参照であることがわかります。 $bRefを使用して作成された [System.Management.Automation.PSReference]は、変数のコピーです。

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

Value
-----
    3
    6

関連項目