2016-08-04 52 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

相关问题