写在最前面

这几天一直在公司接受培训,都是一些基础的知识,同时也乘着这个机会巩固一下自己的基础,基础太重要了。前些时一直看的是多线程方面的知识,接下来我会写一些其他方面的知识,毕竟作为一个实习新人得和自己从事的具体方向靠近,不过感觉前些时的多线程学的还不够,今后有空还会继续,暂时到此吧、、、

昨天培训的时候有一个问题是关于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的区别的更多相关文章

  1. ref和out的区别,值类型和引用类型的使用

    今天刚刚明白ref和out的区别,只限于个人理解如有不同请赐教,谢谢 首先我感觉ref和out是针对于值类型来说,以前一直认为是针对于引用类型看下面的一段代码 1.首先结果 i=0:ints[0]=0 ...

  2. ref和out的区别?

    ref 和out的区别在面试中会常问到: 首先:两者都是按地址传递的,使用后都将改变原来参数的数值. 其次:ref可以把参数的数值传递进函数,但是out是要把参数清空,就是说你无法把一个数值从out传 ...

  3. ref和out的区别

    ref类型参数是按地址传递,能改变原来的数值.使用ref传参前,变量必须赋值. 带有ref类型参数的函数,不会清空变量,所以离开该函数的时候,所有ref引用的变量可以赋值也可以不赋值. out类型参数 ...

  4. 浅谈C#中ref与out的区别

    在C#这门高级语言中,你是否注意过ref与out的用法?你是否为在调用方法时需要多个返回值呢?不用急,接下来,我们去一起去研究一下这个问题... 其实呢,C#语言中,参数的传递一共有两种方法,值传递和 ...

  5. C#中的ref和out的区别

    转载原地址 http://www.cnblogs.com/gjahead/archive/2008/02/28/1084871.html ref和out的区别在C# 中,既可以通过值也可以通过引用传递 ...

  6. C#中ref和out的区别浅析

    这篇文章主要介绍了C#中ref和out的区别浅析,当一个方法需要返回多个值的时候,就需要用到ref和out,那么这两个方法区别在哪儿呢,需要的朋友可以参考下   在C#中通过使用方法来获取返回值时,通 ...

  7. 参数修饰符ref,out ,params的区别

    参数修饰符ref,out ,params的区别 C#中有三个关键字-ref,out ,params,可是这三个之间的区别你都明白了吗? 那么我们就来认识一下参数修饰符ref,out ,params吧, ...

  8. ref与out的区别、冒泡排序、普通排序,以及二分法查询

    一.首先我们先讲一下ref与out的区别和使用方法: 1.ref与out的区别: out:需要在使用前声明变量,分配地址但不能赋值,但是需要在使用中的时候需要初始化(进入方法体中的时候需要先赋值在使用 ...

  9. Spring框架xml配置中属性ref与value的区别

    1.spring批量扫描mybatis的mapper,使用value 2.spring管理mybatis的单个mapper,用的是ref 虽然引用的是同一个bean,但两个对象的属相类型明显不一样,一 ...

随机推荐

  1. Android之按钮

     Button 表示一个按钮.用户点击后会作出响应.具体的响应行为需要我们来定义(一 般通过监听器来处理).  Button 是 TextView 的子类,因此,原则上,TextView 的属性设置均 ...

  2. 开放封闭原则(OCP)

    开放封闭原则 转:http://baike.baidu.com/view/2493421.htm转:http://dev.csdn.net/article/38/38826.shtm 开放封闭原则(O ...

  3. 返璞归真vc++之感言

    本人自述,大专学历,感觉自己也属于好学型学生,历任班上学习委员3年有余,参与学校项目几多个,不知道不觉从11年毕业已有3个年头,3年来,不敢苟同自己的生活方式,奈何人生无奈..从刚开始的电子商务公司转 ...

  4. 【转帖】error C2296: “^”: 非法,左操作数包含“double”类型

    想要实现 ,写的C++程序为 double x; x=2^3; 结果程序总是出现这样的错误:error C2296: “^”: 非法,左操作数包含“double”类型 后来才发现操作符“^”,在C++ ...

  5. iOS 非ARC基本内存管理系列 2-多对象内存管理(2)

    /* 多对象内存管理: 以人拥有车为例涉及到@property底层set方法管理内存的实现 注意:人在换车的时候要进行当前传入的车和人所拥有的车进行判断 */ /******************* ...

  6. amcharts 网页绘图插件

    Amcharts是一组js图表,你可以免费使用在你的网站和基于网络的产品(非开源). Amcharts可以从简单的json提取数据,也可以从动态数据读取生成,比如PHP, .NET, Ruby on ...

  7. Node.js之【express 安装问题】

    经常在全局安装express后,在cmd里面会找不到express命令, 本地模式安装express:'express' 不是内部或外部命令,也不是可运行的程序或批处理文件. 1.先全局安装expre ...

  8. 伪元素content的应用

    日常开发中,我们常用:before,:after来实现一些效果,比如 – 边框 – 图标 此时的content中只是为了伪元素能渲染出来而声明 1 2 3 div:before{ content: & ...

  9. C/C++错误分析errno,perror,strerror和GetLastError()函数返回的错误代码的意义

    在C语言编译中,经常会出现一些系统的错误,这些错误如果在编译的时候不能很好的“预见”,会使系统“崩溃”,常见的捕获错误函数有: errno #include<errno.h> 这个变量是程 ...

  10. CodeForces 18C

    Description Once Bob took a paper stripe of n squares (the height of the stripe is 1 square). In eac ...