列表通过ref传递 – 帮我解释一下这个行为
看看下面的程序:
class Test { List<int> myList = new List<int>(); public void TestMethod() { myList.Add(100); myList.Add(50); myList.Add(10); ChangeList(myList); foreach (int i in myList) { Console.WriteLine(i); } } private void ChangeList(List<int> myList) { myList.Sort(); List<int> myList2 = new List<int>(); myList2.Add(3); myList2.Add(4); myList = myList2; } }  我假设myList会通过ref ,输出会 
 3 4 
 该列表确实是“通过ref传递”,但只有sortfunction生效。 下面的语句myList = myList2; 没有效果。 
所以输出结果实际上是:
 10 50 100 
 你能帮我解释一下这个行为吗? 如果确实myList不是通过引用 (从myList = myList2没有生效), myList.Sort()如何生效? 
我甚至假设这个声明不生效,结果是:
 100 50 10 
	
 你正在传递一个对列表的引用 ,但是你没有通过引用传递列表variables – 所以当你调用ChangeList 时,variables的值 (即引用 – 思考“指针”)被复制 – 并更改为 ChangeList 中 的参数 不会被TestMethod看到。 
尝试:
 private void ChangeList(ref List<int> myList) {...} ... ChangeList(ref myList); 
 然后传递一个对局部variables myRef (在TestMethod声明); 现在,如果您在ChangeList重新分配参数,您也将在 TestMethod重新分配variables。 
最初,它可以用graphics表示如下:

 然后,sorting应用myList.Sort(); 
 最后,当你做: myList' = myList2 ,你失去了参考,但不是原来的,收集保持sorting。 

 如果通过引用( ref )使用myList'和myList将会变成相同的(只有一个引用)。 
 注意:我使用myList'来表示您在ChangeList使用的参数(因为您给出了与原始名称相同的名称) 
这是一个理解它的简单方法
- 
您的列表是在堆上创build的对象。 variables myList是对该对象的引用。
- 
在C#中,你永远不会传递对象,你可以通过值来传递它们的引用。 
- 
当您通过 ChangeList传递的引用访问列表对象时(例如,在sorting时),原始列表会更改。
- 
ChangeList方法的赋值是由引用的值决定的,因此不会对原始列表进行更改(仍然在堆上,但是不再在方法variables上引用)。
这个链接将帮助你理解C#中的引用。 基本上,当一个引用types的对象被值传递给一个方法时,只有该对象上可用的方法才能修改该对象的内容。
例如,List.sort()方法更改列表内容,但是如果将某个其他对象分配给相同的variables,则该分配对于该方法是本地的。 这就是为什么myList保持不变。
如果我们通过使用ref关键字来传递引用types的对象,那么我们可以将一些其他对象分配给同一个variables,并且改变整个对象本身。
  C#只是通过值传递一个浅拷贝,除非有问题的对象执行ICloneable (显然List类没有)。 
 这意味着它复制List本身,但对列表中的对象的引用保持不变; 也就是说,指针继续引用与原始List相同的对象。 
 如果您更改新List引用的值的值,则也会更改原始List (因为它引用的是相同的对象)。 但是,您然后将myList完全引用的内容更改为新的List ,现在只有原始List引用这些整数。 
阅读“传递参数”这篇MSDN文章中的“ 传递引用types参数”部分以获取更多信息。
“如何克隆C#中的通用列表”从StackOverflow谈到如何制作一个列表的深层副本。
虽然我同意以上所有人的说法。 我对这个代码有不同的看法。 基本上你将新列表分配给本地variablesmyList而不是全局。 如果将ChangeList(List myList)的签名更改为private void ChangeList(),则会看到3,4的输出。
这是我的推理…即使列表通过引用传递,认为它通过值传递指针variables当您调用ChangeList(myList)您传递指针(全球)myList。 现在这个存储在(本地)myListvariables中。 所以现在你的(本地)myList和(全局)myList指向相同的列表。 现在你做一个sorting=>它的工作原因是(本地)myList引用原始(全局)myList接下来你创build一个新的列表,并指定你的(本地)myList指针。 但只要函数退出(本地)myListvariables被销毁。 HTH
 class Test { List<int> myList = new List<int>(); public void TestMethod() { myList.Add(100); myList.Add(50); myList.Add(10); ChangeList(); foreach (int i in myList) { Console.WriteLine(i); } } private void ChangeList() { myList.Sort(); List<int> myList2 = new List<int>(); myList2.Add(3); myList2.Add(4); myList = myList2; } } 
 使用ref关键字。 
 在这里看明确的参考来理解传递参数。 
 具体来说,看看这个 ,了解代码的行为。 
 编辑: Sort工作在同一个引用(即通过值),因此,这些值是有序的。 然而,分配一个新的实例参数将无法正常工作,因为参数是通过值传递,除非你把ref 。 
 把ref放在你的案例中,你可以改变指向List的新实例的引用。 没有ref ,你可以在现有的参数上工作,但不能指向其他的东西。