#powershell
#powershell
Вопрос:
Я создаю новый объект (1) с некоторыми свойствами. Я передаю этот объект функции (1), которая затем вызывает другую функцию (2). Функция (2) сама создает объект (2) того же типа и возвращает его с Write-Output
. Затем обратно в функцию (1) объекту (1) присваивается возвращаемое значение. Поскольку объекты передаются по ссылке, я бы ожидал, что объект (1) будет обновлен за пределами области действия функции. Но это не так.
Основной сценарий:
$RootFolder = "C:xyz"
. "$RootFolderFunctionFile - Copy.ps1"
. "$RootFolderFile - Copy.ps1"
$Object_Test = [PSCustomObject]::new()
$Object_Test | Add-Member -MemberType NoteProperty -Name "a" -Value 0
$Object_Test | Add-Member -MemberType NoteProperty -Name "b" -Value 0
Write-Host "Before function call: $Object_Test"
Initialize-ObjectMutation -Object $Object_Test
Write-Host "After function call: $Object_Test"
Функция(1) (‘File — Copy.ps1’):
function Initialize-ObjectMutation {
[CmdletBinding()]
param (
[Parameter(Mandatory=$true)] [PSCustomObject]$Object
)
Write-Host "Before function call (inside): $Object"
$Object = New-Object
Write-Host "After function call (inside): $Object"
}
Функция(2) (‘FunctionFile — Copy.ps1’):
function New-Object {
$Object = [PSCustomObject]::new()
$Object | Add-Member -MemberType NoteProperty -Name "a" -Value 1
$Object | Add-Member -MemberType NoteProperty -Name "b" -Value 1
Write-Output $Object
}
Вывод:
Before function call: @{a=0; b=0}
Before function call (inside): @{a=0; b=0}
After function call (inside): @{a=1; b=1}
After function call: @{a=0; b=0}
Не могли бы вы сказать мне, что я делаю не так, или какую концепцию я здесь неправильно понял? Пожалуйста, также не стесняйтесь давать советы о том, как я мог бы решить это лучшим способом.
В реальной жизни функция (1) сделала бы еще кое-что и с другой рукой, полной переменных. На самом деле это оболочка для функций, подобных function(2).
Комментарии:
1. Не вызывайте
[PSCustomObject]::new()
внутри функции. Вместо этого просто обновите переданный объект.2. Большое спасибо! Это работает. Отметил бы это как ответ, поскольку в моих глазах он выглядит более гладким, чем ответ от Хассана. Можете ли вы, пожалуйста, объяснить, почему он не работал так, как я это делал?
Ответ №1:
Это один из способов заставить его работать, используя мой собственный $ RootFolder. Объект передается по ссылке, а значения копируются из возвращающей функции.
main.ps1
$RootFolder = "H:Codingstack"
. "$RootFolderFunctionFile - Copy.ps1"
. "$RootFolderFile - Copy.ps1"
$Object_Test = [PSCustomObject]::new()
$Object_Test | Add-Member -MemberType NoteProperty -Name "a" -Value 0
$Object_Test | Add-Member -MemberType NoteProperty -Name "b" -Value 0
Write-Host "Before function call: $Object_Test"
Initialize-ObjectMutation -Object ([ref]$Object_Test)
Write-Host "After function call: $Object_Test"
File — Copy.ps1
function Initialize-ObjectMutation {
[CmdletBinding()]
param (
[Parameter(Mandatory=$true)][ref]$Object
)
Write-Host "Before function call (inside): $($Object.value)"
$return = New-Object
$Object.value.a = $return.a;
$Object.value.b = $return.b;
Write-Host "After function call (inside): $($Object.value)"
}
FunctionFile — Copy.ps1
function New-Object {
$Object = [PSCustomObject]::new()
$Object | Add-Member -MemberType NoteProperty -Name "a" -Value 1
$Object | Add-Member -MemberType NoteProperty -Name "b" -Value 1
return $Object
}
Результаты
PS H:Codingstack> ./main.ps1
Before function call: @{a=0; b=0}
Before function call (inside): @{a=0; b=0}
After function call (inside): @{a=1; b=1}
After function call: @{a=1; b=1}
Комментарии:
1. Привет, Хассан, большое спасибо, это работает! Но я действительно надеялся, что смогу избежать этого [ref] … Может кто-нибудь объяснить, почему объект не был передан по ссылке в первой строке? Это работает, если в функции ‘New-Object’ не создан новый объект. Это потому, что $Object становится ссылкой на «новый объект» из New-Object?
2. Эй, это также работает, если я делаю это в ‘File — Copy.ps1’:
$Object_New = New-Object; $Object.a = $Object_New.a; $Object.b = $Object_New.b
.