c#引用类型方法参数的关键字ref深度解析
- 时间:2015年04月02日 15:28:06 来源:魔法猪系统重装大师官网 人气:17732
昨天在垒代码的时候遇到了一个基础没打牢就会暴露的问题。传递给方法的参数为类(class)时,在方法中所做的修改赋值不一定会最终改变到原始的变量上。
举一个例子,如果一个方法Action(List
用代码来分析此案例:
static void Main(string[] args)
{
int i = 0;
int refI = 0;
List
List
TestStruct(i);
TestRefStruct(ref refI);
TestClass(list);
TestRefClass(ref refList);
Console.WriteLine("i: {0}\r\nrefI: {1}\r\nlist: {2}\r\nrefList: {3}", i, refI,
list.Select(x => x.ToString()).Aggregate((x, y) => x + "," + y),
refList.Select(x => x.ToString()).Aggregate((x, y) => x + "," + y));
Console.ReadKey();
}
static void TestStruct(int input)
{
input = 10;
}
static void TestRefStruct(ref int input)
{
input = 10;
}
static void TestClass(List
{
input.Add(5);
input = new List
input.Add(10);
}
static void TestRefClass(ref List
{
input.Add(5);
input = new List
input.Add(10);
}
调试程序,最后输出
i: 0
refI: 10
list: 0,1,2,5
refList: 10
在函数TestStruct中,传入一个值类型的参数,没有对传递进去的参数i做任何的修改。
在函数TestRefStruct中,传入值类型的参数,通过引用传递参数ref,函数中对input进行的任何改变都影响到了refI上,所做的编辑修改全部保留过来。最终refI的值为10。
在函数TestClass中,传入一个引用类型的参数,在函数中,对input重新赋值之前所做的修改都保留了下来,影响了list的值。而在对input重新赋值之后的所有修改编辑,都和list没有任何关联了。
在函数TestRefClass中,传入一个引用类型的参数,同时,参数前面加上ref的约束,函数中,对input进行的任何编辑都影响了refList。最终refList的值为new List
有一定.net基础的人都可以很清晰的理解第一、二和第四种情况。但是第三种情况常常会给我们留下陷阱。
如何理解和正确的对待函数传递的参数为引用类型的情况?我的理解是:
第三种情况下,传递给函数的变量A提供的是一个引用地址,函数会自动生成一个变量B,同时用传递进来的引用地址对这个变量B赋值,这时,传递进来的变量A和函数内调用的变量B共一个引用地址,所做的修改会同步的影响另一个参数。如果在函数内部,出现了一个input = new List
下面模拟代码呈现:
List
{//进入函数
List
B.Add(5);//由于他们是引用类型,共一个引用地址,所做修改相互影响。此时A的值也一起改变。
B = new List
B.Add(10);//A不变。
}//出函数,B释放,A继续存在。
个人理解。如果不足请补充。