Sdílet prostřednictvím


about_Ref

Krátký popis

Popisuje, jak vytvořit a použít proměnnou referenčního typu.

Dlouhý popis

Proměnné můžete funkcím předat odkazem nebo hodnotou. Když předáte proměnnou podle hodnoty, předáváte kopii dat. Když předáte proměnnou odkazem, předáte odkaz na původní hodnotu. To umožňuje funkci změnit hodnotu proměnné, která je jí předána. Odkazové typy se vytvářejí pomocí [ref], což je akcelerátor typů pro typ [System.Management.Automation.PSReference].

Primárním účelem [ref] je povolit předávání proměnných PowerShellu odkazem na parametry metody .NET označené jako ref, outnebo in. Můžete také definovat vlastní funkci PowerShellu, která převezme parametry typu [ref]. V tomto použití se [ref] použije na proměnnoua výsledná instance [ref] se dá použít k nepřímé změně hodnoty této proměnné.

V následujícím příkladu funkce změní hodnotu proměnné předané do ní. V PowerShellu jsou celá čísla typy hodnot, takže se předávají podle hodnoty. Proto je hodnota $var beze změny mimo rozsah funkce.

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

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

V následujícím příkladu je proměnná obsahující Hashtable funkci předána funkci. Hashtable je typ objektu, takže ve výchozím nastavení je předán funkci odkazem.

Při předávání proměnné odkazem může funkce změnit data a tato změna se po spuštění funkce zachovají.

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

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

Funkce přidá nový pár klíč-hodnota, který zůstane mimo obor funkce.

Zápis funkcí pro příjem referenčních parametrů

Funkce můžete kódovat tak, aby jako referenci přebíjel parametr bez ohledu na typ předaných dat. To vyžaduje, abyste zadali typ parametrů jako [ref].

Při použití odkazů musíte pro přístup k datům použít Value vlastnost [ref] typu.

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

Pokud chcete předat proměnnou parametru, který očekává odkaz, musíte proměnnou přetypovat jako odkaz.

Důležitý

Jsou vyžadovány závorky a závorky.

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

Předávání odkazů na metody .NET

Některé metody .NET mohou vyžadovat předání proměnné jako odkazu. Pokud definice metody používá klíčová slova in, outnebo ref u parametru, očekává odkaz.

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

Metoda TryParse se pokusí analyzovat řetězec jako celé číslo. Pokud je metoda úspěšná, vrátí $truea výsledek je uložen v proměnné, kterou jste předali odkazem.

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

Odkazy a obory

Odkazy umožňují změnit hodnotu proměnné v nadřazené oblasti v rámci podřízeného oboru.

# 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

Změnila se pouze proměnná referenčního typu.

Použití [ref] jako držitel předmětu pro obecné účely

Můžete také použít [ref] jako držák objektů pro všeobecné použití. V tomto použití se [ref] použije na hodnotu místo proměnné. Obvykle je to instance typu hodnoty, například číslo. Ve většině scénářů můžete místo toho použít běžnou proměnnou nebo parametr. Tato technika je však užitečná ve scénářích, kdy předání explicitního držitele hodnot není žádoucí (pro stručnost) nebo není možné, například v hodnotách parametrů bloku skriptu.

Můžete například použít hodnoty parametrů bloku skriptu k výpočtu hodnoty NewName parametru Rename-Item rutiny. Rutina Rename-Item umožňuje převést položky do ní. Příkaz spustí skriptblock předaný NewName pro každou položku v kanálu. Skriptblock se spustí v podřízené oblasti. Úprava proměnné v oboru volajícího přímo nepomůže a v tomto kontextu nemůžete předat argumenty do bloku skriptu.

V tomto příkladu blok skriptu předaný parametru NewName zvýší hodnotu $iRef pro každou položku v kanálu. Skriptblock vytvoří nový název přidáním čísla na začátek názvu souboru.

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

Rozdíl mezi [ref] a [System.Management.Automation.PSReference]

Proměnná referenčního typu se vytvoří pomocí akcelerátoru typu [ref] nebo přímým zadáním typu [System.Management.Automation.PSReference]. I když [ref] je akcelerátor typů pro [System.Management.Automation.PSReference], chovají se jinak.

  • Když použijete [ref] k přetypování proměnné, PowerShell vytvoří referenční objekt, který obsahuje odkaz na původní instanci proměnné.
  • Pokud použijete [System.Management.Automation.PSReference] k přetypování proměnné, PowerShell vytvoří referenční objekt, který obsahuje kopii proměnné, a ne odkaz na původní instanci.

Například následující skript vytvoří proměnnou $x a dva referenční objekty.

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

Value
-----
    1
    1

V tomto okamžiku mají oba referenční objekty stejnou hodnotu jako $int. Přidáním různých hodnot do referenčních objektů vidíme, že $aRef, který byl vytvořen pomocí [ref], je odkaz na původní instanci $int. $bRef, který byl vytvořen pomocí [System.Management.Automation.PSReference], je kopie proměnné.

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

Value
-----
    3
    6

Viz také