2010-07-08 138 views
-1

可能重複:
List<int> in c#列表輸出

我有以下程序。我對輸出感到困惑。

該行 -
Console.WriteLine(listIsARefType.Count)輸出0而不是1.任何想法爲什麼?

class Program 
{ 
    static void Main(string[] args) 
    { 
     ListTest d = new ListTest(); 
     d.Test(); 
    } 
} 


class ListTest 
{ 
    public void ModifyIt(List<int> l) 
    { 
     l = returnList(); 
    } 

    public void Test() 
    { 
     List<int> listIsARefType = new List<int>(); 
     ModifyIt(listIsARefType); 
     Console.WriteLine(listIsARefType.Count); // should have been 1 but is 0 
     Console.ReadKey(true); 
    } 

    public List<int> returnList() 
    { 
     List<int> t = new List<int>(); 
     t.Add(1); 
     return t; 
    } 
} 
+6

爲什麼你會將自己的問題標記爲另一個自己的問題的可能*重複?如果它是重複的,請將它們一起滾動,否則請澄清兩個問題,以便明確它們的區別。 – 2010-07-08 23:40:56

回答

2

ModifyIt方法名是誤導性的:它不修改列表,它與一個新的列表替換它。

因此,雖然List<int>是一個引用類型,您傳遞的值是引用。當您將其更改爲指向方法中不影響調用方法中的引用的新List時。

5

默認情況下,.Net中的所有內容均通過,值爲,即使是引用類型也是如此。與引用類型的區別在於它是通過值傳遞的引用本身。因此,當您調用ModifyIt()函數時,您會將參考副本傳遞給該函數。該功能然後改變複製的參考。原始列表引用仍然完好無損,列表未更改。您的代碼應該如下所示:

void ModifyIt(List<int> t) 
{ 
    t.Add(1); 
} 

您會看到現在列表確實發生了變化。你也可以這樣做:

void ModifyIt(ref List<int> t) 
{ 
    t = returnList(); 
} 

但是,你應該贊成前者的風格與後者。如果你已經有一些像returnList()功能,你真的需要一個功能對這些項目添加到現有列表中,像這樣做:

void ModifyIt(List<int> t) 
{ 
    t.AddRange(returnList()); 
} 
1

你正在創建的List<int>一個新的實例,併爲其分配。你不能這樣做,因爲當函數返回時,你傳遞的參數仍然是對舊列表的引用。

你需要做的是使用ref參數,像這樣:

public void ModifyIt(ref List<int> l) 
{ 
    l = returnList(); 
} 

然後調用它像這樣:

ModifyIt(ref listIsARefType); 

你會發現,這將功能如預期。

1

以下行:

List<int> listIsARefType = new List<int>(); 

創建一個新的列表。列表中的項目數是0,下一行的「修飾」列表中(但不是真的,因爲這是問題!)

ModifyIt(listIsARefType); 

所以,當你認爲您添加的東西,你實際上沒有。讓我們看看會發生什麼,當ModifyIt()被調用:

l = returnList(); 

簡單地分配計數1的List<int>l但是 - 這裏的重要部分:

參考l只是參數。您有不是更改了什麼listIsARefType參考。所以,listIsARefType仍然包含0個項目。 l包含1個項目,但只要ModifyIt()完成就會丟失。

其他人可以更好地解釋這裏發生了什麼,這很重要。 Jon Skeet在Parameter passing in C#上有這篇出色的文章。