Dela via


about_Ref

Kort beskrivning

Beskriver hur du skapar och använder en referenstypvariabel.

Lång beskrivning

Du kan skicka variabler till funktioner efter referens eller värde. När du skickar en variabel efter värde skickar du en kopia av data. När du skickar en variabel med referensskickar du en referens till det ursprungliga värdet. Detta gör att funktionen kan ändra värdet för variabeln som skickas till den. Referenstyper skapas med hjälp av [ref], som är typacceleratorn för [System.Management.Automation.PSReference] typ.

Det primära syftet med [ref] är att aktivera överföring av PowerShell-variabler med referens till .NET-metodparametrar som markerats som ref, outeller in. Du kan också definiera en egen PowerShell-funktion som tar [ref] typparametrar. I den här användningen tillämpas [ref] på en variabel, och den resulterande [ref]-instansen kan användas för att indirekt ändra variabelns värde.

I följande exempel ändrar funktionen värdet för variabeln som skickas till den. I PowerShell är heltal värdetyper, vilket innebär att de skickas som värden. Därför är värdet för $var oförändrat utanför funktionens omfång.

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

$var = 10
Test -data $var
$var
10

I följande exempel skickas en variabel som innehåller en Hashtable till en funktion. Hashtable är en objekttyp så som standard skickas den till funktionen som referens.

När du skickar en variabel med referens kan funktionen ändra data och den ändringen kvarstår när funktionen har körts.

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

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

Funktionen lägger till ett nytt nyckel/värde-par som finns kvar utanför funktionens omfång.

Skriva funktioner för att acceptera referensparametrar

Du kan koda dina funktioner för att ta en parameter som referens, oavsett vilken typ av data som skickas. Detta kräver att du anger parametertypen som [ref].

När du använder referenser måste du använda Value egenskapen för typen [ref] för att komma åt dina data.

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

Om du vill skicka en variabel till en parameter som förväntar sig en referens måste du skriva cast-variabeln som referens.

Viktig

Hakparenteserna och parenteserna krävs båda.

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

Skicka referenser till .NET-metoder

Vissa .NET-metoder kan kräva att du skickar en variabel som referens. När metodens definition använder nyckelorden in, outeller ref på en parameter förväntar den sig en referens.

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

Metoden TryParse försöker parsa en sträng som ett heltal. Om metoden lyckas returneras $true, och resultatet lagras i variabeln som du skickade med referens.

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

Referenser och omfång

Referenser tillåter att värdet för en variabel i det överordnade omfånget ändras inom ett underordnat omfång.

# 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

Endast referenstypens variabel har ändrats.

Använda [ref] som objekthållare för generell användning

Du kan också använda [ref] som objekthållare för generell användning. I den här användningen tillämpas [ref] på ett värde i stället för en variabel. Vanligtvis är värdet en instans av en värdetyp, till exempel ett tal. I de flesta scenarier kan du använda en vanlig variabel eller parameter i stället. Den här tekniken är dock användbar i scenarier där det inte är lämpligt att skicka en explicit värdehållare (för korthet) eller inte möjligt, till exempel i parametervärden för skriptblock.

Du kan till exempel använda parametervärden för skriptblock för att beräkna värdet för parametern NewName för cmdleten Rename-Item. Med cmdleten Rename-Item kan du skicka objekt till den. Kommandot kör skriptblocket som skickades till NewName- för varje objekt i pipelinen. Skriptblocket körs i en barnscope. Att ändra en variabel i anroparens omfång direkt hjälper inte och du kan inte skicka argument till skriptblocket i den här kontexten.

I det här exemplet ökar skriptblocket som skickas till parametern NewName värdet för $iRef för varje objekt i pipelinen. Skriptblocket skapar ett nytt namn genom att lägga till ett tal i början av filnamnet.

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

Skillnad mellan [ref] och [System.Management.Automation.PSReference]

En referenstypvariabel skapas med hjälp av [ref] typaccelerator eller genom att ange [System.Management.Automation.PSReference] typ direkt. Även om [ref] är en typaccelerator för [System.Management.Automation.PSReference]fungerar de annorlunda.

  • När du använder [ref] för att omvandla en variabel skapar PowerShell ett referensobjekt som innehåller en referens till den ursprungliga instansen av variabeln.
  • När du använder [System.Management.Automation.PSReference] för att omvandla en variabel skapar PowerShell ett referensobjekt som innehåller en kopia av variabeln i stället för en referens till den ursprungliga instansen.

Följande skript skapar till exempel en variabel $x och två referensobjekt.

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

Value
-----
    1
    1

I det här läget har båda referensobjekten samma värde som $int. Genom att lägga till olika värden i referensobjekten kan vi se att $aRef, som skapades med [ref], är en referens till den ursprungliga instansen av $int. $bRef, som skapades med [System.Management.Automation.PSReference], är en kopia av variabeln.

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

Value
-----
    3
    6

Se även