2016-08-04 73 views
2

我注意到有趣的動作,當我改變列表內部的某個方法,並拋出此方法內的異常,然後超出方法列表的範圍不會改變。列表沒有改變方法外

如何更改強制該列表以更改catch塊?用完了?

List<string> list = null; 
try 
{ 
    list = new List<string>{"1", "2", "3"}; 
    ChangeMyList(list); 
} 
catch 
{ 
    //here list has 3 elements , why ? 
} 

void ChangeMyList(List<string> list) 
{ 
    list = list.Except(new List<string>{"1", "2"}).ToList(); 
    //here this list has only one element 
    throw new Exception(); 
} 
+0

列表對象是在try塊的內部範圍內聲明的,因此甚至不抓塊你 – Fabjan

+0

代碼是沒有得到編譯存在。 ChangeMyList方法中的代碼如何工作:List (「1」,「2」)? – ehh

+1

我更新了你的代碼以實際編譯。 – Jamiec

回答

5

內部ChangeMyListlist是參考源列表的副本在外部範圍指向list。分配給本地參考不會影響調用者中的參考。您可以使用ref按引用傳遞list

void ChangeMyList(ref List<string> list) 
{ 
    list = list.Except(new List<string>("1", "2")).ToList(); 
    //here this list has only one element 
    throw new Exception(); 
} 

然後

List<string> list = new List<string>{"1", "2", "3"}; 
ChangeMyList(ref list); 
+0

哇,我認爲如果你像傳遞List一樣通過引用傳遞,那麼如果你在內部修改,那麼外部也會發生變化,相反當你通過像int這樣的值傳遞時,它是如何工作的? – kosnkov

+2

@kosnkov - 你通過引用,通過使用'ref'或'out',你沒有在你的問題中做。參數默認傳值,對於引用類型來說意味着引用被複制,所以你有兩個對同一個列表對象的引用。你可以通過兩個引用來改變列表(例如,通過調用列表中的「Add」或「Remove」),但是如果你想讓分配在調用者中可見,則必須通過引用傳遞。 – Lee

2

這不是因爲異常的;您的列表沒有被更改,因爲在您調用該函數時複製對該函數的引用,如list中的函數是父範圍中的list的副本,並且對其進行的任何更改都不會對原始範圍進行更改。

有兩種解決方法:

要麼讓你的函數返回list,並將其存儲回原來的變量:

try { 
    having List<string> list = new List<string>{"1", "2", "3"}; 
    list = ChangeMyList(list); 
} catch() { 
} 


List<string> ChangeMyList(List<string> list) 
{ 
    list = list.Except(new List<string>("1", "2")); 
    return list; 
} 

或者你可以簡單地用ref關鍵字來表示通過列表該功能將對其進行修改:

try { 
    having List<string> list = new List<string>{"1", "2", "3"}; 
    ChangeMyList(ref list); 
} catch() { 
} 


void ChangeMyList(ref List<string> list) 
{ 
    list = list.Except(new List<string>("1", "2")); 
} 
+0

哇,我認爲如果你像傳遞List一樣通過引用傳遞,那麼如果你在內部修改,那麼外部也會發生變化,與通過像int這樣的值傳遞時相反...所以它是如何工作的? – kosnkov

+0

* list *不會被複制,它被複制的列表引用*這是一個誤導性答案。 – Jamiec

1

答案已經給出,但僅適用於那些像我一樣的人第二它以圖形的方式更好:

enter image description here

相關問題