我想逐行打印自定义对象中的所有项目.我用过的陈述是:
TestObject ([PSCustomObject]@{item1=1 ;item2=2; item3=3},[PSCustomObject]@{item1=4;item2=5;item3=6}) -Verbose
Run Code Online (Sandbox Code Playgroud)
我的功能定义如下:
function TestObject
{
[CmdLetBinding()]
Param(
[parameter(Mandatory=$True]
[object[]]$objectNames
)
Begin{}
Process
{
foreach ($object in $objectNames)
{
$myItems =@()
$myItems += $object
foreach ($o in $myItems.GetEnumerator())
{
Write-Verbose "---------------$o--------------"
foreach ($i in $o)
{
Write-Verbose "Name:$i.Key Value:$i.Value"
}
}
Write-Verbose "$object"
}
}
End{}
}
Run Code Online (Sandbox Code Playgroud)
我期望输出如下:
VERBOSE: ---------------@{item1=1; item2=2; item3=3}--------------
VERBOSE: Name:item1 Value:1
VERBOSE: Name:item2 Value:2
VERBOSE: Name:item3 Value:3
VERBOSE: @{item1=1; item2=2; item3=3}
VERBOSE: ---------------@{item1=4; item2=5; item3=6}--------------
VERBOSE: Name:item1 Value:4
VERBOSE: Name:item2 Value:5
VERBOSE: Name:item3 Value:6
VERBOSE: @{item1=4; item2=5; item3=6}
Run Code Online (Sandbox Code Playgroud)
相反,我得到了这个结果:
假设我知道自定义对象的格式是由分号分隔的对(键,值)的集合,我如何拆分自定义对象中的项目?
你混淆哈希表和自定义对象.仅仅因为你可以从另一个创建一个并不意味着它们的行为相同.可以通过枚举哈希表来GetEnumerator()生成DictionaryEntry带有Key和Value属性的对象列表.
PS C:\> $ht = @{item1=1 ;item2=2; item3=3}
PS C:\> $ht
Name Value
---- -----
item2 2
item3 3
item1 1
PS C:\> "$ht"
System.Collections.Hashtable
PS C:\> $ht.GetType().FullName
System.Collections.Hashtable
PS C:\> $ht.GetEnumerator() | % { $_.GetType().FullName }
System.Collections.DictionaryEntry
System.Collections.DictionaryEntry
System.Collections.DictionaryEntry
PS C:\> $ht.GetEnumerator() | % { '{0} = {1}' -f $_.Key, $_.Value }
item2 = 2
item3 = 3
item1 = 1
当您将哈希表转换为自定义对象时,它将停止为哈希表(即使其字符串表示仍然看起来像哈希表),并且不再表现得像哈希表:
PS C:\> $o = [PSCustomObject]$ht
PS C:\> $o
item2 item3 item1
----- ----- -----
2 3 1
PS C:\> "$o"
@{item2=2; item3=3; item1=1}
PS C:\> $o.GetType().FullName
System.Management.Automation.PSCustomObject
PS C:\> $o.GetEnumerator()
Method invocation failed because [System.Management.Automation.PSCustomObject]
does not contain a method named 'GetEnumerator'.
At line:1 char:1
+ $o.GetEnumerator()
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (GetEnumerator:String) [],
RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
要枚举对象的属性,请使用其内在属性:
PS C:\> $o.PSObject.Properties
MemberType : NoteProperty
IsSettable : True
IsGettable : True
Value : 2
TypeNameOfValue : System.Int32
Name : item2
IsInstance : True
MemberType : NoteProperty
IsSettable : True
IsGettable : True
Value : 3
TypeNameOfValue : System.Int32
Name : item3
IsInstance : True
MemberType : NoteProperty
IsSettable : True
IsGettable : True
Value : 1
TypeNameOfValue : System.Int32
Name : item1
IsInstance : True
PS C:\> $o.PSObject.Properties | % { '{0} = {1}' -f $_.Name, $_.Value }
item2 = 2
item3 = 3
item1 = 1
至于为什么输出字符串看起来不像你期望的那样:PowerShell不会在字符串中进行复杂的变量扩展."$i.Value"被扩展为字符串表示$i后跟字符串".Value".如果需要字符串中对象的属性,则需要使用字符串连接:
"Name: " + $i.Name + ", Value: " + $i.Value
Run Code Online (Sandbox Code Playgroud)
子表达式:
"Name: $($i.Name), Value: $($i.Value)"
Run Code Online (Sandbox Code Playgroud)
或格式运算符:
"Name: {0}, Value: {1}" -f $i.Name, $i.Value
Run Code Online (Sandbox Code Playgroud)
将您的功能简化为以下内容:
function Test-Object {
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true)]
[array]$ObjectNames
)
foreach ($o in $ObjectNames) {
foreach ($i in $o.PSObject.Properties) {
Write-Verbose "Name: $($i.Name), Value: $($i.Value)"
}
}
}
Run Code Online (Sandbox Code Playgroud)
它应该做你期望的.
| 归档时间: |
|
| 查看次数: |
1198 次 |
| 最近记录: |