为什么这样
Get-WinUserLanguageList | Where-Object LanguageTag -eq en-US
返回空列表(似乎它不过滤值),但这
(Get-WinUserLanguageList) | Where-Object LanguageTag -eq en-US
有效吗?通常我不需要()
,但是在这种情况下,它们是强制性的,但是为什么呢?
答案 0 :(得分:3)
通常我不需要(),但在这种情况下,它们是强制性的,但是为什么呢?
(...)
强制枚举,由管道中包含的命令对集合输出的元素进行枚举。
这不是必须的,但是在您的情况下,因为 Get-WinUserLanguageList
表现出非标准行为 :而不是输出多个结果对象< em>一条到管道,它发出整个集合 [1] 作为单个输出对象 。
(...)
,下一个管道段中的命令-在您的情况下为Where-Object
-因此仅接收一个输入-整个集合-并在< em> it ,而不是一一对应。LanguageType
属性,因此没有任何匹配项,并且您也不会获得任何输出。 [2] 如注释中所述,您可以将命令的输出通过管道传递到Get-Member
,以查看其输出对象的(不同的)类型。对于标准cmdlet,您会看到单个对象输出的类型,而不是集合类型。
[1]具体来说,该集合是类型为[System.Collections.Generic.List[Microsoft.InternationalSettings.Commands.WinUserLanguage]]
的通用列表。
[2]您在命令中使用简化的PSv3 + 比较语句语法-Where-Object LanguageType -eq en-US
-而不是更冗长但更灵活的脚本块语法- Where-Object { $_.LanguageType -eq 'en-US' }
。如果您使用了后者,那么您的命令将不小心返回整个集合,从而有效地返回了所有语言。原因是只有脚本块语法将成员枚举应用于输入集合,这意味着即使$_
本身没有.LanguageTag
属性,< em> elements ,它们的值作为 array 返回。对于LHS数组,-eq
充当过滤器,并且只要en-US
在返回的值中 中,仍将考虑-eq
操作$true
,导致输入对象(整个集合)通过。
this GitHub issue中讨论了两种看似等效的语法形式之间这种令人惊讶的行为差异。
答案 1 :(得分:2)
Get-WinUserLanguageList
返回一个System.Generic.Collection.List
对象的数组。该基础列表是您需要过滤的内容。
将cmdlet放在括号中可以展开基础集合,而不必迭代返回数组中的每个索引。 mklement0的答案进一步说明了这种行为,以及为什么Get-WinUserLanguageList
与大多数其他返回集合的cmdlet的工作原理不同。
答案 2 :(得分:1)
如上所述,您将获得一个列表对象,而不是您期望的WinUserLanguage对象。
PS C:\Users\admin user> $test = Get-WinUserLanguageList
PS C:\Users\admin user> $test.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True List`1 System.Object
PS C:\Users\admin user> $test[0].GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True False WinUserLanguage System.Object
您也可以使用它。
(Get-WinUserLanguageList).where({$_.LanguageTag -eq 'en-US'})
答案 3 :(得分:-2)
基金会:) 选中获取成员。 它是返回数组。