我有一个这样的对象数组
$all = @(
@{ Name = 'First'; Method = { FirstMethod 1 }; Description = "First Description"; }
@{ Name = 'Second'; Description = "Second Description" }
@{ Name = 'Third'; Method = { ThirdMethod }; Description = "Third Description" }
)
每个对象都有一个名称(字符串),一个描述(字符串)和一个方法(其中包含一个函数及其可选)
FirstMethod
和SecondMethod
看起来像这样:
Function FirstMethod
{
param($number)
Write-Host "$number - some other things"
return $number
}
Function ThirdMethod
{
Write-Host "Second called"
return 'test'
}
我正在遍历$all
中的所有项目,并尝试调用Method
参数(如果存在)
Function RunAll
{
foreach($item in $all)
{
If($item.Method)
{
Write-Host "It has method and its running it"
$returned_from_method = $item.Method
Write-Host "Value returned from method: $returned_from_method"
}
Else
{
Write-Host "Does not have a method!"
}
}
}
因此,我基本上需要的是:当循环位于数组First
中的$returned_from_method = $item.Method
项中时,它应该返回1
(因为它调用FirstMethod
并通过1.并且,当循环位于数组中的Third
项中时,它应返回test
(因为它调用了ThirdMethod
)。
反正我能做到吗?
答案 0 :(得分:2)
您发布的代码既没有定义(自定义)对象也没有方法。它定义了一个哈希表的列表,其中一个键具有脚本块值。在该键上使用点访问将仅返回脚本块的定义,而不调用它。
演示:
PS C:\> $ht = @{Name='foo'; Method={FirstMethod 1}; Description='bar'} PS C:\> $ht.Method FirstMethod 1
即使将哈希表转换为对象,该行为也不会改变:
PS C:\> $obj = [PSCustomObject]$ht PS C:\> $obj.Method FirstMethod 1
要实际调用脚本块,您需要调用脚本块的Invoke()
方法:
PS C:\> $ht.Method.Invoke() 1 - some other things 1 PS C:\> $obj.Method.Invoke() 1 - some other things 1
在哈希表或对象的创建之前或之后定义脚本块中调用的函数,只要在调用脚本块之前定义该函数就无关紧要。您自己的答案中的代码似乎仅能工作,因为您用分组表达式(括号)替换了脚本块(花括号)。但是,这意味着“方法”是根据哈希表的定义进行评估的,并且仅函数的返回值与键一起存储。 Write-Host
输出立即写入控制台,并且不与密钥一起存储。
PS C:\> $ht = @{Name='foo'; Method=(FirstMethod 1); Description='bar'} 1 - some other things PS C:\> $ht.Method 1
要使用实际(脚本)方法创建对象,您需要添加具有正确类型的属性:
PS C:\> $obj | Add-Member -Name 'Method2' -Type ScriptMethod -Value {FirstMethod 2} PS C:\> $obj.Method2() 2 - some other things 2
因此,用于创建对象的代码应如下所示:
$obj1 = [PSCustomObject]@{
Name = 'First'
Description = 'First Description'
}
$obj1 | Add-Member -Name 'Method' -Type ScriptMethod -Value {FirstMethod 1}
$obj2 = [PSCustomObject]@{
Name = 'Second'
Description = 'Second Description'
}
$obj3 = [PSCustomObject]@{
Name = 'Third'
Description = 'Third Description'
}
$obj3 | Add-Member -Name 'Method' -Type ScriptMethod -Value {ThirdMethod}
$all = $obj1, $obj2, $obj3
答案 1 :(得分:-1)
如果有人为此而苦苦挣扎,这就是答案:
方法user.user_skill.skill_lists
和FirstMethod
应该在数组之前声明
然后我需要在ThirdMethod
而不是()
中添加函数。
{}
现在工作正常!