about_Ref

Breve descrizione

Viene descritto come creare e usare una variabile di tipo riferimento.

Descrizione lunga

È possibile passare variabili alle funzioni per riferimento o per valore. Quando si passa una variabile per valore, si passa una copia dei dati. Quando si passa una variabile per riferimento, si passa un riferimento al valore originale. Ciò consente alla funzione di modificare il valore della variabile passata. I tipi di riferimento vengono creati usando [ref], ovvero l'acceleratore di tipi per il tipo di [System.Management.Automation.PSReference].

Lo scopo principale di [ref] consiste nell'abilitare il passaggio di variabili di PowerShell per riferimento ai parametri del metodo .NET contrassegnati come ref, outo in. È anche possibile definire una funzione di PowerShell personalizzata che accetta [ref] parametri di tipo. In questo utilizzo, [ref] viene applicato a una variabile e l'istanza di [ref] risultante può essere usata per modificare indirettamente il valore della variabile.

Nell'esempio seguente la funzione modifica il valore della variabile passata. In PowerShell i numeri interi sono tipi di valore in modo che vengano passati per valore. Di conseguenza, il valore di $var rimane invariato all'esterno dell'ambito della funzione.

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

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

Nell'esempio seguente viene passata una variabile contenente un Hashtable a una funzione. Hashtable è un tipo di oggetto, quindi per impostazione predefinita viene passato alla funzione per riferimento.

Quando si passa una variabile per riferimento, la funzione può modificare i dati e tale modifica viene mantenuta dopo l'esecuzione della funzione.

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

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

La funzione aggiunge una nuova coppia chiave-valore che persiste all'esterno dell'ambito della funzione.

Scrittura di funzioni per accettare parametri di riferimento

È possibile codificare le funzioni per accettare un parametro come riferimento, indipendentemente dal tipo di dati passato. È quindi necessario specificare il tipo di parametri come [ref].

Quando si usano riferimenti, è necessario utilizzare la proprietà Value del tipo di [ref] per accedere ai dati.

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

Per passare una variabile a un parametro che prevede un riferimento, è necessario digitare eseguire il cast della variabile come riferimento.

Importante

Le parentesi quadre e le parentesi sono entrambe obbligatorie.

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

Passaggio di riferimenti ai metodi .NET

Alcuni metodi .NET possono richiedere di passare una variabile come riferimento. Quando la definizione del metodo usa le parole chiave in, outo ref in un parametro, prevede un riferimento.

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

Il metodo TryParse tenta di analizzare una stringa come numero intero. Se il metodo ha esito positivo, restituisce $truee il risultato viene archiviato nella variabile passata per riferimento.

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

Riferimenti e ambiti

I riferimenti consentono di modificare il valore di una variabile nell'ambito padre all'interno di un ambito figlio.

# 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

È stata modificata solo la variabile del tipo di riferimento.

Utilizzo [ref] come titolare di oggetti per utilizzo generico

È anche possibile utilizzare [ref] come titolare di oggetti per utilizzo generico. In questo utilizzo, [ref] viene applicato a un valore anziché a una variabile. In genere, il valore è un'istanza di un tipo valore , come un numero. Nella maggior parte degli scenari è invece possibile usare una variabile o un parametro regolare. Tuttavia, questa tecnica è utile negli scenari in cui il passaggio di un titolare di valore esplicito è indesiderato (per brevità) o non è possibile, ad esempio nei valori dei parametri del blocco di script.

Ad esempio, è possibile usare i valori dei parametri del blocco di script per calcolare il valore di parametro NewName del cmdlet Rename-Item. Il cmdlet Rename-Item consente di inviare tramite pipe gli elementi. Il comando esegue lo scriptblock passato a NewName per ogni elemento della pipeline. Scriptblock eseguito in un ambito figlio. La modifica diretta di una variabile nell'ambito del chiamante non consente di passare argomenti al blocco script in questo contesto.

In questo esempio, lo scriptblock passato al parametro NewName incrementa il valore di $iRef per ogni elemento nella pipeline. Scriptblock crea un nuovo nome aggiungendo un numero all'inizio del nome file.

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

Differenza tra [ref] e [System.Management.Automation.PSReference]

Viene creata una variabile di tipo riferimento usando l'acceleratore di tipo [ref] o specificando direttamente il tipo di [System.Management.Automation.PSReference]. Anche se [ref] è un acceleratore di tipi per [System.Management.Automation.PSReference], si comportano in modo diverso.

  • Quando si usa [ref] per eseguire il cast di una variabile, PowerShell crea un oggetto riferimento che contiene un riferimento all'istanza originale della variabile.
  • Quando si usa [System.Management.Automation.PSReference] per eseguire il cast di una variabile, PowerShell crea un oggetto riferimento che contiene una copia della variabile anziché un riferimento all'istanza originale.

Ad esempio, lo script seguente crea una variabile $x e due oggetti riferimento.

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

Value
-----
    1
    1

A questo punto, entrambi gli oggetti riferimento hanno lo stesso valore di $int. Aggiungendo valori diversi agli oggetti di riferimento, è possibile osservare che $aRef, creato tramite [ref], è un riferimento all'istanza originale di $int. $bRef, creato usando [System.Management.Automation.PSReference], è una copia della variabile .

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

Value
-----
    3
    6

Vedere anche