昨天编码的时候遇到一个问题,基础不打牢就会暴露出来。 当传递给方法的参数是类时,方法中所做的修改赋值最终可能不会更改为原始变量。
比如有一个方法(List lst),方法中对lst进行了很多操作,包括add、new、add等,传入变量List input。 该方法执行后可能会添加输入,但new之后的任何操作都不会被保留。 为什么是这样? 当我第一次学习.net的基础知识时,我知道对于引用类型,引用的地址被传递给方法,而不是实际值。 那么为什么有的操作被保留,有的却没有执行呢?
用代码来分析一下这个案例:
无效主([]参数)
整数 i = 0;
int refI = 0;
列表列表 = new List() { 0, 1, 2 };
列表 = 新列表() { 0, 1, 2 };
(我);
(参考参考I);
(列表);
(参考);
.("i: {0}\r\nrefI: {1}\r\n列表: {2}\r\: {3}", i, refI,
列表。(x => x.())。((x, y) => x + "," + y),
.(x => x.()).((x, y) => x + "," + y));
.();
无效(整数输入)
输入= 10;
void(引用 int 输入)
输入= 10;
void(列表输入)
输入.Add(5);
输入=新列表();
输入.Add(10);
void(参考列表输入)
输入.Add(5);
输入=新列表();
输入.Add(10);
调试程序,最终输出
我:0
参考:10
列表:0,1,2,5
: 10
函数中传入了一个值类型参数,并且不对传入的参数进行任何修改。
函数中传入的是值类型的参数,参数ref则是引用传递的。 对函数中输入的任何更改都会影响 refI,并且所做的所有编辑和修改都将被保留。 refI的最终值为10。
函数中传入了一个引用类型参数,函数中保留了输入重新赋值之前所做的修改,影响了列表的值。 重新分配输入后的所有修改和编辑与列表无关。
函数中传入了一个引用类型的参数,同时在参数前面添加了ref约束。 在该函数中,对输入的任何编辑都会受到影响。 最终值是新列表{10}。
任何有一定.net基础的人都可以清楚地理解第一种、第二种和第四种情况。 但第三种情况常常给我们留下陷阱。
如何理解并正确对待函数传递的参数为引用类型的情况? 我的理解是:
在第三种情况下,传递给函数的变量 A 提供了一个引用地址。 函数会自动生成一个变量B,并使用传入的引用地址给变量B赋值,此时传入的变量A和函数内调用的变量B都有引用地址,修改会影响同步另一个参数。 如果在函数内部,则输入 = new List(); 出现声明。 此时,变量B将被重新赋值给另一个引用地址。 那么,从现在开始,变量B不再与变量A相关,对变量B所做的任何修改都不会影响变量A。
给出如下仿真代码:
List A = new List() { 0, 1, 2 };//传递给函数的变量。
{//输入函数
List B = A;//函数执行后,自动生成B,用A给B赋值。
B.Add(5);//由于它们是引用类型并且共享相同的引用地址,所以修改会互相影响。 此时A的值也随之变化。
B = new List();//重新分配B指向另一个引用地址。 和A没有关系。
B.Add(10);//A保持不变。
}//退出函数,B被释放,A继续存在。
个人理解。 如果不足,请补充。