PS > function test($val){
>> $val | Add-Member -NotePropertyMembers @{Test=10}
>> }
PS > $num = 5
PS > test($num)
PS > $num.Test
10
PS > $num | Get-Member -View Extended
TypeName: System.Int32
Name MemberType Definition
---- ---------- ----------
Test NoteProperty int Test=10
Function arguments of value types are passed by their values and any modifications to them,
including extension of thier members by Add-Member cmdlet, should not be seen by a caller.
A NoteProperty was added to the [int] variable inside the function while passing it by value.
PSVersion 6.2.3
PSEdition Core
GitCommitId 6.2.3
OS Microsoft Windows 10.0.18362
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0鈥
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
All values in PowerShell are "boxed" by design.
小oming from its nature PowerShell cannot handle values like C# - all values are boxed by design and passed by reference. This leads to performance (memory allocations) issues. Implementing argument passing by value in scripts will only worsen this problem (We have some issues for this.). Conversely, PowerShell uses caching to reduce memory allocations.
Really that we can do here - address a specific business scenario if we get it or a hot code path. But again, it will most likely be a movement in the opposite direction from what you request. (We already had such perf PRs.)
/cc @daxian-dbw @SeeminglyScience @mklement0 if they want to add more.
The main thing here is that the parameter $val
is typed as object
. The value stored in $num
is first boxed when it's saved as a variable. Variables in PowerShell are implemented as PSVariable
objects (for the most part) where the value is stored on a property public object Value { get; }
. Since the parameter is also typed as object
, the boxed value is passed to the function. If you change the parameter type to int
it doesn't repro anymore.
@iSazonov @SeeminglyScience thanks, clear explantaion
Most helpful comment
The main thing here is that the parameter
$val
is typed asobject
. The value stored in$num
is first boxed when it's saved as a variable. Variables in PowerShell are implemented asPSVariable
objects (for the most part) where the value is stored on a propertypublic object Value { get; }
. Since the parameter is also typed asobject
, the boxed value is passed to the function. If you change the parameter type toint
it doesn't repro anymore.