2014-10-30 32 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