2017-09-07 3 views
2

誰もこの奇妙なpowershellの動作を説明できますか?私は次のように宣言した場合System.Collections.ArrayListはSystem.Collecitons.HashTableになります

:私はメンバーを取得する場合、あなたが私の全体のcollecitonが表示されますただし

System.Collections.Array.List 
Index Item 
0  {System.Collections.HashTable} 
1  {System.Collections.HashTable} 
2  {System.Collections.HashTable} 

$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}) 

をので...私はこのようになりますオブジェクトを持つ必要があります1つの大きなハッシュテーブルになっています

$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;} 

そして、このような動作は次のとおりです。例えば、私は私の物私が望むようにアクセスできません:あなたが見ることができるように

$MyCollection | %{$_.Val1} 

出力

1 
1 
1 

の予想される出力

1 

を、私たちは今、一つの大きなハッシュテーブルを持っています非常に奇妙な行動をします。誰もPowershellが実際にやっていることを説明できますか?なぜなら、ArrayListコレクション内のHashTableには挑戦的にアクセスしていないからです。

あなたはあなたの例ではGet-Memberが配列の内部、ハッシュテーブルを見ているので、それが巻き出されるパイプラインを経由して配列を渡すと、その任意のコマンドレットを呼び出すなどは単一のハッシュテーブル

+0

'$ MyCollection | %{$ _。Val1} 'の例?現在の出力は、私が構文について期待しているものと同じです。 – Persistent13

答えて

4

に私のデータ構造を平坦化します。

配列であるオブジェクトの型を取得するには、GetType()メソッドを使用して、nameプロパティを調べます。

$MyCollection.GetType() 

IsPublic IsSerial Name          BaseType 
-------- -------- ----          -------- 
True  True  ArrayList        System.Object 

アンスガーWiechersはあなたにも、配列の型を取得するために-InputObjectパラメータを使用できることを下に示しました。

Get-Member -InputObject $MyCollection 

あなたはハッシュテーブル出力の配列からのみ単一の項目をしたい場合、あなたはハッシュテーブルのキーに続いて値をするアレイ内のどのインデックスを指定する必要があります。

$MyCollection[0]['Val1'] 
1 

上記の例は、配列内の最初のオブジェクトのキーVal1に格納された値を返します。他のものを取得するには、インデックス番号を増やすか、キーを変更する必要があります。

+4

'Get-Member -InputObject $ MyCollection'を使用すると、アンロールを回避できます。 –

+0

あなたはアンロールされたものについて詳しく説明できますか?それは、1つのハッシュテーブルに結合されたように見えます。また、私がこのように 'ForEach-Object -InputObject $ MyCollection -Process {$ _}'を実行すると、 'Get-Member'に' $ _'を渡すか、 'Get-Member'に' $ MyCollection'を渡します。まったく同じ。 –

+3

@ JamieMarshall配列をパイプラインに渡すと、配列内の各項目を自動的に反復し、各項目を個別に評価します。 1つの出力しか表示されないのは、 'Get-Member'がパイプラインを通して渡されたアイテムに対して一意の結果を出力するということです。 – TheMadTechnician

関連する問題