2013-02-20 55 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