Compartir a través de


about_Ref

Descripción breve

Describe cómo crear y usar una variable de tipo de referencia.

Descripción larga

Puede pasar variables a funciones por referencia o por valor. Cuando se pasa una variable por valor, se pasa una copia de los datos. Cuando se pasa una variable por referencia, se pasa una referencia al valor original. Esto permite que la función cambie el valor de la variable que se le pasa. Los tipos de referencia se crean mediante [ref], que es el acelerador de tipos para el tipo de [System.Management.Automation.PSReference].

El objetivo principal de [ref] es habilitar el paso de variables de PowerShell mediante referencia a parámetros de método de .NET marcados como ref, outo in. También puede definir su propia función de PowerShell que tome [ref] parámetros de tipo. En este uso, [ref] se aplica a una variable , y la instancia de [ref] resultante se puede usar para modificar indirectamente el valor de esa variable.

En el ejemplo siguiente, la función cambia el valor de la variable que se le pasa. En PowerShell, los enteros son tipos de valor para que se pasen por valor. Por lo tanto, el valor de $var no se modifica fuera del ámbito de la función.

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

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

En el ejemplo siguiente, se pasa una variable que contiene un Hashtable a una función. Hashtable es un tipo de objeto, por lo que de forma predeterminada se pasa a la función por referencia.

Al pasar una variable por referencia, la función puede cambiar los datos y ese cambio persiste después de que se ejecute la función.

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

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

La función agrega un nuevo par clave-valor que persiste fuera del ámbito de la función.

Escritura de funciones para aceptar parámetros de referencia

Puede codificar las funciones para tomar un parámetro como referencia, independientemente del tipo de datos pasados. Esto requiere que especifique el tipo de parámetros como [ref].

Al usar referencias, debe usar la propiedad Value del tipo [ref] para acceder a los datos.

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

Para pasar una variable a un parámetro que espera una referencia, debe escribir la variable como referencia.

Importante

Los corchetes y paréntesis son obligatorios.

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

Pasar referencias a métodos de .NET

Algunos métodos de .NET pueden requerir que pase una variable como referencia. Cuando la definición del método usa las palabras clave in, outo ref en un parámetro, espera una referencia.

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

El método TryParse intenta analizar una cadena como un entero. Si el método se realiza correctamente, devuelve $truey el resultado se almacena en la variable que pasó por referencia.

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

Referencias y ámbitos

Las referencias permiten cambiar el valor de una variable en el ámbito primario dentro de un ámbito secundario.

# 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

Solo se cambió la variable del tipo de referencia.

Usar [ref] como titular de objetos de uso general

También puede usar [ref] como titular de objetos de uso general. En este uso, [ref] se aplica a un valor de en lugar de una variable. Normalmente, el valor es una instancia de un tipo de valor de , como un número. En la mayoría de los escenarios, puede usar una variable o un parámetro normales en su lugar. Sin embargo, esta técnica es útil en escenarios en los que pasar un titular de valor explícito no es deseado (por brevedad) o no es posible, como en valores de parámetros de bloque de script.

Por ejemplo, puede usar valores de parámetros de bloque de script para calcular el valor de parámetro NewName del cmdlet Rename-Item. El cmdlet Rename-Item permite canalizar elementos a él. El comando ejecuta el scriptblock pasado al NewName para cada elemento de la canalización. El scriptblock se ejecuta en un ámbito secundario. La modificación de una variable en el ámbito del autor de la llamada directamente no ayuda y no se pueden pasar argumentos al bloque de scripts en este contexto.

En este ejemplo, el bloque de scripts pasado al parámetro NewName incrementa el valor de para cada elemento de $iRef la canalización. El scriptblock crea un nuevo nombre agregando un número al principio del nombre de archivo.

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

Diferencia entre [ref] y [System.Management.Automation.PSReference]

Se crea una variable de tipo de referencia mediante el acelerador de tipos [ref] o especificando directamente el tipo [System.Management.Automation.PSReference]. Aunque [ref] es un acelerador de tipos para [System.Management.Automation.PSReference], se comportan de forma diferente.

  • Cuando se usa [ref] para convertir una variable, PowerShell crea un objeto de referencia que contiene una referencia a la instancia original de la variable.
  • Cuando se usa [System.Management.Automation.PSReference] para convertir una variable, PowerShell crea un objeto de referencia que contiene una copia de la variable, en lugar de una referencia a la instancia original.

Por ejemplo, el siguiente script crea una variable $x y dos objetos de referencia.

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

Value
-----
    1
    1

En este punto, ambos objetos de referencia tienen el mismo valor que $int. Al agregar valores diferentes a los objetos de referencia, podemos ver que $aRef, que se creó mediante [ref], es una referencia a la instancia original de $int. $bRef, que se creó mediante [System.Management.Automation.PSReference], es una copia de la variable .

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

Value
-----
    3
    6

Consulte también