Ваш первый фрагмент концептуально корректен и работает как задумано - сам по себе он не выдает ошибку «Значение свойства не может быть найдено для этого объекта».
Вы видите ошибку только как часть полного сценария, на который ссылаетесь, из-за следующей строки:
$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'