2013-02-20 50 views
1

我很困惑。我不明白爲什麼Powershell中的foreach表現與C#不同。Powershell中的枚舉與管道

這個簡單的代碼不產生輸出:

@{a=1; b=2} | %{ $_.key } 

這個我在Linqpad使用C#做了一個近似給出了輸出,我期望:

var ht = new Hashtable(); 
ht["a"] = 1; 
ht["b"] = 2; 

foreach (DictionaryEntry kvp in ht) 
{ 
    kvp.Key.Dump(); 
} 

// output 

a 
b 

如果我列舉的按鍵成員散列表,我可以做我需要的。但我不明白爲什麼枚舉散列表本身不會返回鍵值對。事實上,它似乎返回對象本身:

>  @{a=1; b=2} | %{ $_.gettype() } 

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

什麼是Powershell在這裏做?

回答

3

PowerShell管道將「展開」數組和集合(一個級別),但不會散列表。如果要枚舉PowerShell中的哈希表的鍵值對,請調用.getenumerator()方法:

$ht = @{a=1;b=2} 
$ht.GetEnumerator() 



Name       Value                
----       -----                
a        1                 
b        2  
+0

Yay,這就是我所需要的,謝謝!順便說一句,你怎麼知道這個?有沒有解釋展開的文檔?我甚至沒有想過在我的搜索中使用這個關鍵字,但現在我知道它我看到很多點擊。 – scobi 2013-02-20 03:26:44

+2

我不記得我第一次瞭解到這一點,或者如果是通過發現,但您可以輕鬆地自行驗證。構建一個二維數組,並通過管道發送給foreach對象。每個對象都將是其中一個二級數​​組。 – mjolinor 2013-02-20 03:32:14

+0

事實上,如果你想阻止管道展開數組,你需要傳遞逗號前綴,如:@(1,2,3)然後將整個數組實例作爲單個管道對象傳遞,而不是迭代內容。 (就我個人而言,我發現展開非常討厭,它似乎永遠是我想要的相反,但誰知道,也許我只是沒有充分利用該功能的最佳) – 2013-02-20 05:03:34