Skip to content

Commit 2937b3d

Browse files
about_Ref.md: Relationship between [ref] and [PSReference] (#11580)
* about_Ref.md: Relationship between [ref] and [PSReference] Added a new section, "Relationship between [ref] and System.Management.Automation.PSReference" to about_Ref.md. * Updated examples and added more context * Fix typo --------- Co-authored-by: Sean Wheeler <sean.wheeler@microsoft.com>
1 parent 7bdebdd commit 2937b3d

File tree

3 files changed

+344
-65
lines changed

3 files changed

+344
-65
lines changed

reference/5.1/Microsoft.PowerShell.Core/About/about_Ref.md

Lines changed: 115 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,34 @@
11
---
22
description: Describes how to create and use a reference type variable. You can use reference type variables to permit a function to change the value of a variable that is passed to it.
33
Locale: en-US
4-
ms.date: 08/24/2018
4+
ms.date: 12/12/2024
55
online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_ref?view=powershell-5.1&WT.mc_id=ps-gethelp
66
schema: 2.0.0
77
title: about_Ref
88
---
9-
109
# about_Ref
1110

1211
## Short description
1312

14-
Describes how to create and use a reference type variable. You can use
15-
reference type variables to permit a function to change the value
16-
of a variable that is passed to it.
13+
Describes how to create and use a reference type variable.
1714

1815
## Long description
1916

20-
You can pass variables to functions *by reference* or *by value*.
17+
You can pass variables to functions _by reference_ or _by value_. When you pass
18+
a variable _by value_, you are passing a copy of the data. When you pass a
19+
variable _by reference_, you are passing a reference to the original value.
20+
This allows the function to change the value of the variable that is passed to
21+
it.Reference types are created using `[ref]`, which is the type accelerator for
22+
the `[System.Management.Automation.PSReference]` type.
2123

22-
When you pass a variable *by value*, you are passing a copy of the data.
24+
The primary purpose of `[ref]` is to enable passing PowerShell variables by
25+
reference to .NET method parameters marked as `ref`, `out`, or `in`. You can
26+
also define your own PowerShell function that take `[ref]` type parameters. In
27+
this usage, `[ref]` is applied to a _variable_, and the resulting `[ref]`
28+
instance can be used to indirectly modify that variable's value.
2329

2430
In the following example, the function changes the value of the variable passed
25-
to it. In PowerShell, integers are value types so they are passed by value.
31+
to it. In PowerShell, integers are value types so they're passed by value.
2632
Therefore, the value of `$var` is unchanged outside the scope of the function.
2733

2834
```powershell
@@ -41,10 +47,10 @@ $var
4147
```
4248

4349
In the following example, a variable containing a `Hashtable` is passed to a
44-
function. `Hashtable` is an object type so by default it is passed to the
45-
function *by reference*.
50+
function. `Hashtable` is an object type so by default it's passed to the
51+
function _by reference_.
4652

47-
When passing a variable *by reference*, the function can change the data and
53+
When passing a variable _by reference_, the function can change the data and
4854
that change persists after the function executes.
4955

5056
```powershell
@@ -67,14 +73,14 @@ Test New Text
6773
The function adds a new key-value pair that persists outside of the function's
6874
scope.
6975

70-
### Writing functions to accept reference parameters
76+
## Writing functions to accept reference parameters
7177

7278
You can code your functions to take a parameter as a reference, regardless of
7379
the type of data passed. This requires that you specify the parameters type
74-
as `System.Management.Automation.PSReference`, or `[ref]`.
80+
as `[ref]`.
7581

76-
When using references, you must use the `Value` property of the
77-
`System.Management.Automation.PSReference` type to access your data.
82+
When using references, you must use the `Value` property of the `[ref]` type to
83+
access your data.
7884

7985
```powershell
8086
Function Test([ref]$data)
@@ -86,7 +92,7 @@ Function Test([ref]$data)
8692
To pass a variable to a parameter that expects a reference, you must type
8793
cast your variable as a reference.
8894

89-
> [!NOTE]
95+
> [!IMPORTANT]
9096
> The brackets and parenthesis are BOTH required.
9197
9298
```powershell
@@ -99,7 +105,7 @@ $var
99105
3
100106
```
101107

102-
### Passing references to .NET methods
108+
## Passing references to .NET methods
103109

104110
Some .NET methods may require you to pass a variable as a reference. When
105111
the method's definition uses the keywords `in`, `out`, or `ref` on a
@@ -127,7 +133,7 @@ PS> $number
127133
15
128134
```
129135

130-
### References and scopes
136+
## References and scopes
131137

132138
References allow the value of a variable in the parent scope to be changed
133139
within a child scope.
@@ -149,10 +155,96 @@ $i = 0;$iRef = 1
149155

150156
Only the reference type's variable was changed.
151157

158+
## Using `[ref]` as a general-purpose object holder
159+
160+
You can also use `[ref]` as a general-purpose object holder. In this usage,
161+
`[ref]` is applied to a _value_ instead of a variable. Typically, the value is
162+
an instance of a _value type_, like a number. In most scenarios you can use a
163+
regular variable or parameter instead. However, this technique is useful in
164+
scenarios where passing an explicit value holder is undesired (for brevity) or
165+
not possible, such as in script-block parameter values.
166+
167+
For example, you can use script-block parameter values to calculate the value
168+
of **NewName** parameter of the `Rename-Item` cmdlet. The `Rename-Item` cmdlet
169+
allows you to pipe items to it. The command run the script block passed to the
170+
**NewName** for each item in the pipeline. The script block run in a child
171+
scope. Modifying a variable in the caller's scope directly won't help and you
172+
can't pass arguments to the script block in this context.
173+
174+
In this example, the script block passed to the **NewName** parameter
175+
increments the value of `$iRef` for each item in the pipeline. The script block
176+
creates a new name by adding a number to the beginning of the filename.
177+
178+
```powershell
179+
$iRef = [ref] 0
180+
Get-ChildItem -File $setPath |
181+
Rename-Item -NewName { '{0} - {1}' -f $iRef.Value++,$_.Name }
182+
```
183+
184+
## Difference between `[ref]` and `[System.Management.Automation.PSReference]`
185+
186+
A reference type variable is created using
187+
188+
Even though `[ref]` is a type accelerator for
189+
`[System.Management.Automation.PSReference]`, they behave differently.
190+
191+
- When you use `[ref]` to cast a variable, PowerShell creates reference object
192+
that contains reference to the original instance of the variable.
193+
- When you use `[System.Management.Automation.PSReference]` to cast a variable,
194+
PowerShell creates reference object that contains a copy of the variable,
195+
rather than a reference to the original instance.
196+
197+
For example, the following script creates a variable `$x` and two reference
198+
objects.
199+
200+
```powershell
201+
PS> $int = 1
202+
PS> $aRef = [ref] $int
203+
PS> $bRef = [System.Management.Automation.PSReference] $int
204+
PS> $int
205+
1
206+
PS> $aRef, $bRef
207+
208+
Value
209+
-----
210+
1
211+
1
212+
```
213+
214+
At this point, both reference objects have the same value as `$int`. By adding
215+
different values to the reference objects, we can see that `$aRef`, which was
216+
created using `[ref]`, is a reference to the original instance of `$int`.
217+
`$bRef`, which was created using `[System.Management.Automation.PSReference]`,
218+
is a copy of the variable.
219+
220+
```powershell
221+
PS> $aRef.Value+=2
222+
PS> $bRef.Value+=5
223+
PS> $int
224+
3
225+
PS> $aRef, $bRef
226+
227+
Value
228+
-----
229+
3
230+
6
231+
```
232+
152233
## See also
153234

154-
- [about_Variables](about_Variables.md)
155-
- [about_Environment_Variables](about_Environment_Variables.md)
156-
- [about_Functions](about_Functions.md)
157-
- [about_Script_Blocks](about_Script_Blocks.md)
158-
- [about_Scopes](about_scopes.md)
235+
- [about_Variables][06]
236+
- [about_Environment_Variables][01]
237+
- [about_Functions][02]
238+
- [about_Script_Blocks][04]
239+
- [about_Scopes][03]
240+
- [about_Type_Accelerators][05]
241+
- [System.Management.Automation.PSReference][07]
242+
243+
<!-- link references -->
244+
[01]: about_Environment_Variables.md
245+
[02]: about_Functions.md
246+
[03]: about_scopes.md
247+
[04]: about_Script_Blocks.md
248+
[05]: about_Type_Accelerators.md
249+
[06]: about_Variables.md
250+
[07]: xref:System.Management.Automation.PSReference

0 commit comments

Comments
 (0)