簡単な説明
参照型変数を作成して使用する方法について説明します。
詳細な説明
参照またはby 値関数に変数を渡すことができます。 変数 by 値を渡すと、データのコピーが渡されます。 参照で変数 [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
を含む変数が関数に渡されます。
変数 参照渡すと、関数はデータを変更でき、その変更は関数の実行後も保持されます。
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 メソッドでは、変数を参照として渡す必要があります。 メソッドの定義でパラメーターのキーワード 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
参照とスコープ
参照を使用すると、親スコープ内の変数の値を子スコープ内で変更できます。
# 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
関連項目
PowerShell