Передать строки по ссылке в Powershell? - PullRequest
0 голосов
/ 28 июня 2018

Как я могу передать строки, ссылаясь на родительскую область?

Это не работает, так как строки не являются приемлемыми "значениями".

function Submit([ref]$firstName){ 
    $firstName.value =  $txtFirstName.Text 
}

$firstName = $null
Submit([ref]$firstName)
$firstName

Ошибка: «Свойство« значение »не может быть найдено для этого объекта; убедитесь, что оно существует и может быть установлено»

Это не приводит к ошибке, но также не меняет переменную:

$firstName = "nothing"

function Submit([ref]$firstName){ 
    $firstName =  $txtFirstName.Text 
} 

Submit([ref]$firstName)
$firstName

Edit:

Выполнение первого блока кода само по себе работает. Однако при попытке сделать это в моем скрипте он снова возвращает ошибку. Я исправил это достаточно для того, чтобы назначить переменную и сделать то, что я хочу, но все равно выдает ошибку, и мне было интересно, как это исправить. Я думаю, это потому, что он не любит переменные, они меняются во время сеанса. Вот ссылка на мой скрипт

https://github.com/InconspicuousIntern/Form/blob/master/Form.ps1

Ответы [ 2 ]

0 голосов
/ 29 июня 2018

Ваш первый фрагмент концептуально корректен и работает как задумано - сам по себе он не выдает ошибку «Значение свойства не может быть найдено для этого объекта».

Вы видите ошибку только как часть полного сценария, на который ссылаетесь, из-за следующей строки:

$btnSubmit.Add_Click({ Submit })

Эта строка приводит к тому, что ваша Submit функция вызывается без аргументов , что, в свою очередь, приводит к тому, что значение параметра $firstName равно $null, что, в свою очередь, вызывает указанную выше ошибку при назначении до $firstName.Value.

В противоположность этому следующий вызов Submit, как и в вашем первом фрагменте, является правильным:

Submit ([ref] $firstName)  # Note the recommended space after 'Submit' - see below.

[ref] $firstName создает (временную) ссылку на переменную $firstName вызывающего абонента , которая внутри Submit связывается с (локальной) переменной параметра $firstName (два может, но не обязательно и, возможно, лучше не иметь того же имени), где $firstName.Value может затем использоваться для изменения переменной $firstName вызывающей стороны.


Синтаксическая заметка : Я намеренно поместил пробел между Submit и ([ref] $firstName), чтобы прояснить одну вещь:

Здесь (...) (круглые скобки) не включают в себя весь аргумент list , как в случае вызова метода , они заключают в себе single аргумент [ref] $firstName - по необходимости, потому что это выражение не будет признано таковым в противном случае.

Вызовы функций в PowerShell анализируются в так называемом режиме аргумента , синтаксис которого больше похож на синтаксис вызова консольных приложений: аргументы разделяются пробелом и обычно требуют только цитирования если они содержат специальные символы.

Например, если вы также хотите передать строку 'foo' в качестве 2-го позиционного параметра в Submit:

Submit ([ref] $firstName) foo

Обратите внимание, как два аргумента разделены пробелом и как foo не нужно заключать в кавычки.


Что касается альтернативного подхода :

Основная цель

[ref] - включить вызовы методов .NET, которые имеют параметры ref / out, и, как показано выше, использование [ref] нетривиально.

Для вызовов функций PowerShell обычно существуют более простые решения.

Например, вы можете передать пользовательский объект в вашу функцию и позволить функции обновить свои свойства значениями, которые вы хотите вернуть, что, естественно, позволяет множественным значениям быть " вернулся "; e.g.:

function Submit($outObj){ 
    $outObj.firstName = 'a first name'
}

# Initialize the custom object that will receive values inside
# the Submit function.
$obj = [pscustomobject] @{ firstName = $null }

# Pass the custom object to Submit.
# Since a custom object is a reference type, a *reference* to it
# is bound to the $outObj parameter variable.
Submit $obj

$obj.firstName # -> 'a first name'

Кроме того, вы можете просто позволить Submit создать собственный объект и просто вывести it:

function Submit { 
    # Construct and (implicitly) output a custom
    # object with all values of interest.
    [pscustomobject] @{ 
        firstName = 'a first name' 
    } 
}

$obj = Submit

$obj.firstName # -> 'a first name'
0 голосов
/ 28 июня 2018

Пожалуйста, попробуйте это и посмотрите, получаете ли вы те же результаты? Это работает для меня, и я действительно не сильно изменился.

$txtFirstName = [PSCustomObject]@{
    Text = "Something"
}

function Submit([ref]$var){ 
    $var.value =  $txtFirstName.Text 
}



$firstName = $null
Submit([ref]$firstName)
$firstName
...