2014-10-30 30 views
1

为什么我在下面得到不同的输出取决于我使用的还是foreach? 用foreach,当你改变每个元素的值时,你不是在改变它的引用吗?我会认为做$ row =“d”会使该元素指向“d”,但显然它不会这样做,就好像$ row只是一个副本。更改Foreach中的元素对于

[Collections.Generic.List[String]]$list = New-Object '[Collections.Generic.List[String]]' 
$list.Add("a") 
$list.Add("b") 
$list.Add("c") 

#foreach ($row in $list) 
for ($i = 0; $i -lt $list.Count; $i++) 
{ 
#$row = "d" 
$list[$i] = "d" 
} 

Write-Host $list 

<# 
Output: with foreach: "a b c" 
with for: "d d d" 
#> 
+0

你是什么意思?我的代码中没有C#,它是纯粹的Powershell。 – 2014-10-30 03:00:35

+0

我的错误。我看到的所有对'[Collections.Generic.List [String]]的引用都与c#有关。也许我的powershell版本低于你的版本。 – Matt 2014-10-30 03:05:57

+0

@Matt C#只是一种针对.NET框架的语言(如Powershell)。 Collections.Generic.List [String]只是.NET中的一个类,可以在C#中使用(Collections.Generic.List )或Powershell([Collections.Generic.List [String]]) – 2014-10-30 03:53:53

回答

1

使用foreach(和ForEach-Object)导致环路是副本内的元件。你可以在循环内改变它,但一旦你超出范围就会消失。

+1

这真的是一个问题范围和理解儿童范围的工作方式。我本来希望看到更多关于此的内容。即告诉他们'get-help about_scopes'或者提供一个[指向technet页面的链接](http://technet.microsoft.com/en-us/library/hh847849.aspx),它讨论范围。 – TheMadTechnician 2014-10-30 01:36:47

+1

我认为它不仅仅适用于范围。如果变量是块本地的(而且它是),但它是一个像预期的海报那样的引用,那么范围并不重要,因为它仍然会更新引用的对象。我认为,这是一个副本,这是真正的问题。 – briantist 2014-10-30 02:10:19

+0

@briantist它不会更新引用的对象,因为被复制的引用($ row)会被分配一个全新的引用(指向字符串对象“d”的指针),而不会改变原始引用。 然后,因为它的范围只在foreach循环中,所以它被垃圾收集,并且被复制的原始对象保持不变。 – 2014-10-30 03:08:40