关于ref与out的区别
写在最前面
这几天一直在公司接受培训,都是一些基础的知识,同时也乘着这个机会巩固一下自己的基础,基础太重要了。前些时一直看的是多线程方面的知识,接下来我会写一些其他方面的知识,毕竟作为一个实习新人得和自己从事的具体方向靠近,不过感觉前些时的多线程学的还不够,今后有空还会继续,暂时到此吧、、、
昨天培训的时候有一个问题是关于ref和out的区别,悲催的我不知道,只晓得它们可以做引用传递,具体区别都没一个概念额,貌似当年教我们C#初级的尹老师提到过一个数字交换实现可以用这个,不过当时也就仅此仅此,今天来学习下下
首先声明下哈,此文参考了网上部分文章内容,然后结合自己的了解和总结,有不对的尽管拍砖
关于ref
经常听到值类型和引用类型,其实本质就是一个存储值一个存储地址,看看下面一段代码:
public class Test
{
public int num;
public Test(int x)
{
this.num = x;
}
public void ChangeNum(Test x)
{
x = new Test();
}
}
class Program
{
static void Main(string[] args)
{
Test ts = new Test();
ts.ChangeNum(ts);
Console.WriteLine(ts.num);
Console.ReadKey();
}
}
对于以上代码,你认为会输出什么结果?10?100?正确结果是10,猜100的肯定有疑问了、、、
接下来我改两个位置,就不复制整个了,贴出改位置的两个位置,如下所示:
ts.ChangeNum(ref ts); //改上面第18行
public void ChangeNum(ref Test x) //改上面第8行
对于这次的结果又得探讨了,10?还是100?正确结果为100

以上截图,左边是原始代码变量ts和x的地址,右边是修改两个位置后的ts和x的地址,从上面我们可以清晰的看见左图ts地址(0x05f0eb2c)和x地址(0x05f0eacc)不同,右图中ts的地址(0x0568ee6c)和x的地址(0x0568ee6c)相同。就是由于原始代码中Main函数中的ts和Test中的x不是同一个变量,所以后面执行18行代码不会对num值产生任何影响,而后面的两行代码就不同,因为所指向的是同一个变量,所以结果自然得以修改变为100
关于out
还是来看一段代码,事实比较好说话,呵呵:
public class Test
{
public int num;
public Test(int x)
{
this.num = x;
}
public void ChangeNum(out Test x)
{
x = new Test();
}
}
class Program
{
static void Main(string[] args)
{
Test ts = new Test();
Test x;
ts.ChangeNum(out x);
Console.WriteLine(ts.num);
Console.WriteLine(x.num);
Console.ReadKey();
}
}
以上这段代码执行打印的两个结果也是不同的,分别打印10和100,原理和上面差不多一样,是不是感觉和上面讲的ref很有点象,没错,所以有了今天的标题“关于ref与out的区别”,接下来谈谈其区别吧!
关于out和ref的区别
作为都可以作为引用传递,区别在于值传递。ref传递前必须初始化,而out不必初始化,就算初始化,也会被无视之,out 作为输出参数,可以解决函数只有一个返回值的问题
static void Main(string[] args)
{
Program pg = new Program();
int x;
pg.Method_1(out x);
Console.WriteLine(x);
int y = ;
pg.Method_2(ref y);
Console.WriteLine(y);
Console.ReadKey();
} public void Method_1(out int x)
{
x = ; //这一句必须要,不然报错
Console.WriteLine("调用Medthod_1");
} public void Method_2(ref int x)
{
x++;
Console.WriteLine("调用Medthod_2");
}
运行结果:

怀旧一下当年尹老师讲的a=5和b=10,a与b数值交换,就是用的ref
public void yy(ref int x,ref int y)
{
int temp;
temp = x;
x = y;
y = temp;
}
static void Main(string[] args)
{
Program pg = new Program();
int a = ;
int b = ;
Console.WriteLine("a:" + a + ",b:" + b);
pg.yy(ref a,ref b);
Console.WriteLine("a:"+a+",b:"+b);
Console.ReadKey();
}
然后以上代码改为用out实现:
public void yy(int a,int b,out int x,out int y)
{
x = b;
y = a;
}
static void Main(string[] args)
{
Program pg = new Program();
int a = ;
int b = ;
Console.WriteLine("a:" + a + ",b:" + b);
pg.yy(a,b,out a,out b);
Console.WriteLine("a:"+a+",b:"+b);
Console.ReadKey();
}
自我感觉吧,在很多地方ref和out可以互换,起到相同的作用,区别仅仅在于ref传进去的参数必须在调用前初始化,out不必初始化;ref传进去的参数在函数内部可以直接使用,而out不可以;ref传进去的参数在函数内部可以不被修改,但out必须在离开函数体前进行赋值。个人感觉ref可以更随意的使用,out总有那么点别扭,毕竟必须在内部给其赋值。
实习的第一个双休日
貌似此文扯了些不该扯得,但总的来说都是跟随笔主要内容有些相关啦,接下来由于培训内容的相关,得转移重心了,Linq和EF还得再回去看看,所以后期可能写点哪方面相关知识。晚睡的习惯还木有改过来,这是个问题得治啊,听了一晚上的歌,单曲循环"想把我唱给你听",好晚了,睡觉去也!!!
------如果你觉得此文对你有所帮助,别忘了点击下右下角的推荐咯,谢谢!------
关于ref与out的区别的更多相关文章
- ref和out的区别,值类型和引用类型的使用
今天刚刚明白ref和out的区别,只限于个人理解如有不同请赐教,谢谢 首先我感觉ref和out是针对于值类型来说,以前一直认为是针对于引用类型看下面的一段代码 1.首先结果 i=0:ints[0]=0 ...
- ref和out的区别?
ref 和out的区别在面试中会常问到: 首先:两者都是按地址传递的,使用后都将改变原来参数的数值. 其次:ref可以把参数的数值传递进函数,但是out是要把参数清空,就是说你无法把一个数值从out传 ...
- ref和out的区别
ref类型参数是按地址传递,能改变原来的数值.使用ref传参前,变量必须赋值. 带有ref类型参数的函数,不会清空变量,所以离开该函数的时候,所有ref引用的变量可以赋值也可以不赋值. out类型参数 ...
- 浅谈C#中ref与out的区别
在C#这门高级语言中,你是否注意过ref与out的用法?你是否为在调用方法时需要多个返回值呢?不用急,接下来,我们去一起去研究一下这个问题... 其实呢,C#语言中,参数的传递一共有两种方法,值传递和 ...
- C#中的ref和out的区别
转载原地址 http://www.cnblogs.com/gjahead/archive/2008/02/28/1084871.html ref和out的区别在C# 中,既可以通过值也可以通过引用传递 ...
- C#中ref和out的区别浅析
这篇文章主要介绍了C#中ref和out的区别浅析,当一个方法需要返回多个值的时候,就需要用到ref和out,那么这两个方法区别在哪儿呢,需要的朋友可以参考下 在C#中通过使用方法来获取返回值时,通 ...
- 参数修饰符ref,out ,params的区别
参数修饰符ref,out ,params的区别 C#中有三个关键字-ref,out ,params,可是这三个之间的区别你都明白了吗? 那么我们就来认识一下参数修饰符ref,out ,params吧, ...
- ref与out的区别、冒泡排序、普通排序,以及二分法查询
一.首先我们先讲一下ref与out的区别和使用方法: 1.ref与out的区别: out:需要在使用前声明变量,分配地址但不能赋值,但是需要在使用中的时候需要初始化(进入方法体中的时候需要先赋值在使用 ...
- Spring框架xml配置中属性ref与value的区别
1.spring批量扫描mybatis的mapper,使用value 2.spring管理mybatis的单个mapper,用的是ref 虽然引用的是同一个bean,但两个对象的属相类型明显不一样,一 ...
随机推荐
- Java Servlet-http协议
---恢复内容开始--- 互联网三大基石: url:定位数据 html:显示数据 http:传输数据
- C#Winform版获取Excel文件的内容
public MainForm() { InitializeComponent(); //this.ofd_in.DefaultExt = ".xlsx"; this.ofd_in ...
- android控件的属性
android控件的属性 本节描述android空间的位置,内容等相关属性及属性的含义 第一类:属性值为true或false android:layout_centerHrizontal 水平居中 ( ...
- 应注意的Flex&Bison潜规则
1.Flex的二义性模式 语法分析器匹配输入时匹配尽可能多的字符串 如果两个模式都可以匹配的话,匹配在程序中更早出的模式. 针对这一点的理解,在语法分析文件当中,token的识别,应从特殊到一般的过程 ...
- GetStartupInfo 反调试
在使用 CreateProcess 创建进程时,需要传递 STARTUPINFO 的结构的指针,而常常我们并不会一个一个设置其结构的值,连把其他不用的值清0都会忽略,而 ollydbg 也这样做了,我 ...
- java concurrent包的学习(转)
java concurrent包的学习(转) http://my.oschina.net/adwangxiao/blog/110188 我们都知道,在JDK1.5之前,Java中要进行业务并发时,通常 ...
- C#反编译工具 ILSPY-x64可动态调试-君临汉化版
程序基于著名的ILSpy version 2.1.0.1603 汉化,并增加x64下debugging功能;初衷是网上只有一版是原作者留下的x86版本,实在不想在虚拟机里调试,只有自己动手弄一份x64 ...
- 如何建立一个“绑定友好的”usercontrol--wpf
如何建立一个"绑定友好的"usercontrol--wpf 这几天在打算将以前用winform写的工具程序重构到wpf,顺便学习理解看过的wpf的知识. 因为程序设计到一个Exce ...
- linux centos 安装
本着学习的目的,在自己的电脑上进行 centos 7 安装,记录下这步骤以备忘. 一.Centos 下载 centos 官方(https://www.centos.org/)下载ISO镜像(这是我的下 ...
- jquery 获取 CheckBox 的状态
<td style="width:220px;vertical-align:central;"><input type="checkbox" ...