当我们希望一个已有返回值的方法能够修改我一个外部基本类型的值的时候,我们可以将该参数加上ref关键字作为入参。具体原理其实就是将栈中具体的值替换为了栈的引用,说白了就是地址,幻想一下本来你高考作弊只是后台改了一下自己成绩和学霸一样,学霸的人生没有受到影响,现在你干脆把学霸的试卷改成了自己名字,学霸直接被你影响只能进厂打螺丝了,当然这个比喻不是很贴切,大家理解到意思就行。
那么为什么引用类型的入参我们不需要要添加ref?因为从上图我们能看出来栈中存储的本来就是引用类型的地址,所以引用类型不需要添加ref关键字,当你在方法内部修改了入参的一些属性值,外面的实惨依旧会受到影响。
我们在实际开发中还是能够碰到一些引用类型添加ref的场景。其实道理也是一样的,就是将引用类型的栈的地址传递到了方法中,那么和不添加有啥区别?
Student student1 = new Student("Jack"); Student student2 = new Student("Lucy"); WithoutRef(student1); WithRef(ref student2); Console.WriteLine($"不带ref的方法---{student1.Name}"); Console.WriteLine($"带ref的方法---{student2.Name}"); Console.Read(); //不带ref的方法 static void WithoutRef(Student stu) { stu.Name = "Bruce"; } //不带ref的方法 static void WithRef(ref Student stu) { stu.Name = "Bruce"; } public class Student { public Student(string name) { Name = name; } public string Name { get; set; } }
可以看到结果一样的,两个实例的名字都变了
那我们再看看下面的代码:
Student student1 = new Student("Jack"); Student student2 = new Student("Lucy"); WithoutRef(student1); WithRef(ref student2); Console.WriteLine($"不带ref的方法---{student1.Name}"); Console.WriteLine($"带ref的方法---{student2.Name}"); Console.Read(); //不带ref的方法 static void WithoutRef(Student stu) { stu = new Student("Bruce"); } //不带ref的方法 static void WithRef(ref Student stu) { stu = new Student("Bruce"); } public class Student { public Student(string name) { Name = name; } public string Name { get; set; } }
我们发现第一个不带ref的方法名字没有发生变化。
代码的变化就是第二个例子重新new了一下,我们根据上面的原理分析就能知道为啥。由于ref将引用类型的栈地址传递过去了,new关键字大体就是在堆中开辟一个新空间,然后将空间地址存储到栈中,由于ref将栈地址传递过来了,所以就将栈中的存储地址替换为了新开辟的堆地址了,而不带ref的引用类型本身传递的只是堆中地址的引用,所以new关键字等于说将形参重新开辟空间和分配了,和实参已经不是同一个地方了。
标签:c++,输入,文件,方法,编程,设置,代码,安装,链接,下载,压缩 来源:
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。