System.Collections.ArrayList 变为 System.Collecitons.HashTable
System.Collections.ArrayList becomes System.Collecitons.HashTable
任何人都可以解释这种奇怪的 powershell 行为。
如果我声明如下:
$MyCollection = New-Object System.Collections.ArrayList
$MyCollection.Add(@{'Val1'=1; 'Val2'=2; 'Val3'=3})
$MyCollection.Add(@{'Val1'=1; 'Val2'=2; 'Val3'=3})
$MyCollection.Add(@{'Val1'=1; 'Val2'=2; 'Val3'=3})
所以...我应该有一个 object 看起来像这样:
System.Collections.Array.List
Index Item
0 {System.Collections.HashTable}
1 {System.Collections.HashTable}
2 {System.Collections.HashTable}
但是,如果我成为会员,您会看到我的整个收藏集都变成了一个大哈希 table
$MyCollection | Get-Member
TypeName: System.Collections.Hashtable
Name MemberType Definition
---- ---------- ----------
Add Method void Add(System.Object key, System.Object value), void IDictionary.Add(System.Object key, System.Object value)
Clear Method void Clear(), void IDictionary.Clear()
Clone Method System.Object Clone(), System.Object ICloneable.Clone()
Contains Method bool Contains(System.Object key), bool IDictionary.Contains(System.Object key)
ContainsKey Method bool ContainsKey(System.Object key)
ContainsValue Method bool ContainsValue(System.Object value)
CopyTo Method void CopyTo(array array, int arrayIndex), void ICollection.CopyTo(array array, int index)
Equals Method bool Equals(System.Object obj)
GetEnumerator Method System.Collections.IDictionaryEnumerator GetEnumerator(), System.Collections.IDictionaryEnumerator IDictionary.GetEnumerator(), System.Collections.IEnumerator IEnumerable.GetEn...
GetHashCode Method int GetHashCode()
GetObjectData Method void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context), void ISerializable.GetObjectData(System.Runtime....
GetType Method type GetType()
OnDeserialization Method void OnDeserialization(System.Object sender), void IDeserializationCallback.OnDeserialization(System.Object sender)
Remove Method void Remove(System.Object key), void IDictionary.Remove(System.Object key)
ToString Method string ToString()
Item ParameterizedProperty System.Object Item(System.Object key) {get;set;}
Count Property int Count {get;}
IsFixedSize Property bool IsFixedSize {get;}
IsReadOnly Property bool IsReadOnly {get;}
IsSynchronized Property bool IsSynchronized {get;}
Keys Property System.Collections.ICollection Keys {get;}
SyncRoot Property System.Object SyncRoot {get;}
Values Property System.Collections.ICollection Values {get;}
行为是这样的。例如,我无法以我想要的方式访问我的 object:
$MyCollection | %{$_.Val1}
产出
1
1
1
预期输出
1
如您所见,我们现在有一个大散列 table,其行为非常奇怪。谁能解释一下 Powershell 实际上在做什么?因为它肯定不会访问 ArrayList collection 中的 HashTable。
就像调用任何 cmdlet 一样将我的数据结构扁平化为单个散列 table
当您通过管道传递数组时,它会展开,因此在您的示例中 Get-Member
看到的是数组的内部结构,哈希表。
要获取数组对象的类型,您可以使用 GetType()
方法并查看名称 属性.
$MyCollection.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True ArrayList System.Object
Ansgar Wiechers 在下面展示了您还可以使用 -InputObject
参数来获取数组的类型。
Get-Member -InputObject $MyCollection
如果您只需要哈希表输出数组中的一个项目,您需要指定数组中的哪个索引,您希望值后跟哈希表键。
$MyCollection[0]['Val1']
1
上面的示例 returns 存储在数组中第一个对象的键 Val1
中的值。要获得其他人,您必须增加索引号或更改密钥。
任何人都可以解释这种奇怪的 powershell 行为。
如果我声明如下:
$MyCollection = New-Object System.Collections.ArrayList
$MyCollection.Add(@{'Val1'=1; 'Val2'=2; 'Val3'=3})
$MyCollection.Add(@{'Val1'=1; 'Val2'=2; 'Val3'=3})
$MyCollection.Add(@{'Val1'=1; 'Val2'=2; 'Val3'=3})
所以...我应该有一个 object 看起来像这样:
System.Collections.Array.List
Index Item
0 {System.Collections.HashTable}
1 {System.Collections.HashTable}
2 {System.Collections.HashTable}
但是,如果我成为会员,您会看到我的整个收藏集都变成了一个大哈希 table
$MyCollection | Get-Member
TypeName: System.Collections.Hashtable
Name MemberType Definition
---- ---------- ----------
Add Method void Add(System.Object key, System.Object value), void IDictionary.Add(System.Object key, System.Object value)
Clear Method void Clear(), void IDictionary.Clear()
Clone Method System.Object Clone(), System.Object ICloneable.Clone()
Contains Method bool Contains(System.Object key), bool IDictionary.Contains(System.Object key)
ContainsKey Method bool ContainsKey(System.Object key)
ContainsValue Method bool ContainsValue(System.Object value)
CopyTo Method void CopyTo(array array, int arrayIndex), void ICollection.CopyTo(array array, int index)
Equals Method bool Equals(System.Object obj)
GetEnumerator Method System.Collections.IDictionaryEnumerator GetEnumerator(), System.Collections.IDictionaryEnumerator IDictionary.GetEnumerator(), System.Collections.IEnumerator IEnumerable.GetEn...
GetHashCode Method int GetHashCode()
GetObjectData Method void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context), void ISerializable.GetObjectData(System.Runtime....
GetType Method type GetType()
OnDeserialization Method void OnDeserialization(System.Object sender), void IDeserializationCallback.OnDeserialization(System.Object sender)
Remove Method void Remove(System.Object key), void IDictionary.Remove(System.Object key)
ToString Method string ToString()
Item ParameterizedProperty System.Object Item(System.Object key) {get;set;}
Count Property int Count {get;}
IsFixedSize Property bool IsFixedSize {get;}
IsReadOnly Property bool IsReadOnly {get;}
IsSynchronized Property bool IsSynchronized {get;}
Keys Property System.Collections.ICollection Keys {get;}
SyncRoot Property System.Object SyncRoot {get;}
Values Property System.Collections.ICollection Values {get;}
行为是这样的。例如,我无法以我想要的方式访问我的 object:
$MyCollection | %{$_.Val1}
产出
1
1
1
预期输出
1
如您所见,我们现在有一个大散列 table,其行为非常奇怪。谁能解释一下 Powershell 实际上在做什么?因为它肯定不会访问 ArrayList collection 中的 HashTable。
就像调用任何 cmdlet 一样将我的数据结构扁平化为单个散列 table
当您通过管道传递数组时,它会展开,因此在您的示例中 Get-Member
看到的是数组的内部结构,哈希表。
要获取数组对象的类型,您可以使用 GetType()
方法并查看名称 属性.
$MyCollection.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True ArrayList System.Object
Ansgar Wiechers 在下面展示了您还可以使用 -InputObject
参数来获取数组的类型。
Get-Member -InputObject $MyCollection
如果您只需要哈希表输出数组中的一个项目,您需要指定数组中的哪个索引,您希望值后跟哈希表键。
$MyCollection[0]['Val1']
1
上面的示例 returns 存储在数组中第一个对象的键 Val1
中的值。要获得其他人,您必须增加索引号或更改密钥。