默认情况下,CLR假定所有方法参数都是传值的。
对于引用类型,对一个对象的引用(指向对象的一个指针)会传给方法,但是这个引用本身是以传值的方式传给方法的。方法能修改对象,调用者能看到这些修改。
对于值类型,传给方法的是实例的一个副本。方法获得的是一个值类型实例副本,所以调用者中的实例不受影响。
代码如下:
namespace refDemo2 { class Program { static void Main(string[] args) { int i = 5; AddI(i); Console.WriteLine(i);//显示"5",i的值并没有改变 Console.ReadKey(); } private static void AddI(int v)//v获得的是i的一个副本,调用者中的实例不受影响 { v+= 10; } } }
一,为值类型使用ref和out
namespace refDemo2 { class Program { static void Main(string[] args) { int i = 5; AddI(ref i); Console.WriteLine(i);//显示"15",i的值被改变了 Console.ReadKey(); } private static void AddI(ref int v)//v获得的是一个指向实例对象(值5)的指针 { v+= 10; } } }
二,为引用类型使用ref和out
namespace refDemo3 { class Program { static void Main(string[] args) { string s1 = "Tmac"; string s2 = "Mcgrady"; Swap(s1,s2);//没有使用ref Console.WriteLine(s1);//显示"Tmac" Console.WriteLine(s2);//显示"Mcgrady",为什么值没有交换呢??? } private static void Swap(string a, string b)//a和b获取的是一个分别指向对象s1和s2的指针 { string t = b; b = a; a = t; } } }
容易困惑的地方:s1,s2是引用类型,传给方法Swap的肯定也是指向实例的一个指针,那理论上来讲调用了Swap方法之后s1和s2的值要交换呀,可是实际结果并不如我们所愿,这是为什么呢?
答:就如文章一开头讲的,默认情况下,CLR假定所有方法参数都是传值的,虽然s1和s2是引用类型,调用方法时传递的也是指向实例的指针,但是,指针本身还是以传值方式传给方法的。所以调用者中实例的值并没有得到改变。
要达到我们想要的效果,所以还是必须得使用ref,代码如下:
namespace refDemo3 { class Program { static void Main(string[] args) { string s1 = "Tmac"; string s2 = "Mcgrady"; Swap(ref s1,ref s2); Console.WriteLine(s1);//显示"Mcgrady" Console.WriteLine(s2);//显示"Tmac" } private static void Swap(ref string a,ref string b)//a和b获取的是一个分别指向对象s1和s2的指针 { string t = b; b = a; a = t; } } }
总结:1,从IL和CLR的角度看,ref和out是一样的,它们都会生成相同的IL代码,都导致传递指向实例的一个指针。
2,ref一般用在方法内部对外部的值进行改变的时候。而out一般用在方法有多个返回值的时候。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架