naw*_*fal 14 c# ref argument-passing c#-4.0
如果我没有得到这个非常错误,这种行为对我来说很奇怪.而不是解释,我将在下面发布一个示例代码,请告诉我为什么我得到输出x而不是y.
private void button1_Click(object sender, EventArgs e)
{
List<int> l = new List<int>() { 1, 2, 3 };
Fuss(l);
MessageBox.Show(l.Count.ToString());
}
private void Fuss(List<int> l)
{
l.Add(4);
l.Add(5);
}
Run Code Online (Sandbox Code Playgroud)
输出应该,我假设是3.但我得到输出为5.我理解输出可以是5如果我这样做:
private void button1_Click(object sender, EventArgs e)
{
List<int> l = new List<int>() { 1, 2, 3 };
Fuss(ref l);
MessageBox.Show(l.Count.ToString());
}
private void Fuss(ref List<int> l)
{
l.Add(4);
l.Add(5);
}
Run Code Online (Sandbox Code Playgroud)
chr*_*aut 15
它不像ref传递的那样行事.
void ChangeMe(List<int> list) {
list = new List<int>();
list.Add(10);
}
void ChangeMeReally(ref List<int> list) {
list = new List<int>();
list.Add(10);
}
Run Code Online (Sandbox Code Playgroud)
试试吧.你注意到了区别吗?
如果在没有引用的情况下传递它,则只能更改列表(或任何引用类型)的内容(因为正如其他人所说,您正在传递对堆上对象的引用,从而更改相同的"内存").
但是,您无法更改"list","list"是指向List类型的对象的变量.如果您通过引用传递它,则只能更改"list"(以使其指向其他位置).您将获得该引用的副本,如果已更改,则只能在您的方法中查看.
参数在C#中按值传递,除非它们用ref或out修饰符标记.对于引用类型,这意味着引用按值传递.因此,在Fuss,l是指同一个实例List<int>作为它的调用者.因此,List<int>调用者将看到对此实例的任何修改.
现在,如果l使用ref或标记参数out,则参数将通过引用传递.这意味着,在Fuss,l是作为参数来调用该方法的存储位置的别名.要明确:
public void Fuss(ref List<int> l)
Run Code Online (Sandbox Code Playgroud)
叫做
List<int> list = new List<int> { 1, 2, 3 };
Fuss(list);
Run Code Online (Sandbox Code Playgroud)
现在,in Fuss,l是别名list.特别是,如果您为List<int>to 分配新实例l,则调用者也会看到分配给该变量的新实例list.特别是,如果你说
public void Fuss(ref List<int> l) {
l = new List<int> { 1 };
}
Run Code Online (Sandbox Code Playgroud)
然后调用者现在将看到一个包含一个元素的列表.但如果你说
public void Fuss(List<int> l) {
l = new List<int> { 1 };
}
Run Code Online (Sandbox Code Playgroud)
并打电话给
List<int> list = new List<int> { 1, 2, 3 };
Fuss(list);
Run Code Online (Sandbox Code Playgroud)
然后调用者仍然会看到list有三个元素.
明确?
| 归档时间: |
|
| 查看次数: |
13926 次 |
| 最近记录: |