ref和out都是C#中的关键字,所实现的功能也差不多,都是指定一个参数按照引用传递。
对于编译后的程序而言,它们之间没有任何区别,也就是说它们只有语法区别。
总结起来,他们有如下语法区别: 、ref传进去的参数必须在调用前初始化,out不必,即:
int i;
SomeMethod( ref i );//语法错误
SomeMethod( out i );//通过 、ref传进去的参数在函数内部可以直接使用,而out不可:
public void SomeMethod(ref int i)
{
int j=i;//通过
//...
}
public void SomeMethod(out int i)
{
int j=i;//语法错误
} 、ref传进去的参数在函数内部可以不被修改,但out必须在离开函数体前进行赋值。
ref在参数传递之前必须初始化;而out则在传递前不必初始化,且在 ... 值类型与引用类型之间的转换过程称为装箱与拆箱。 总结:
应该说,系统对ref的限制是更少一些的。out虽然不要求在调用前一定要初始化,但是其值在函数内部是不可见的,也就是不能使用通过out传进来的值,并且一定要在函数内赋一个值。或者说函数承担初始化这个变量的责任。 下面谈谈ref和out到底有什么区别:
关于重载
原则:有out|ref关键字的方法可以与无out和ref关键字的方法构成重载;但如想在out和ref间重载,编译器将提示:不能定义仅在ref和out的上的方法重载
关于调用前初始值
原则:ref作为参数的函数在调用前,实参必须赋初始值。否则编译器将提示:使用了未赋值的局部变量;
out作为参数的函数在调用前,实参可以不赋初始值。
关于在函数内,引入的参数初始值问题
原则:在被调用函数内,out引入的参数在返回前至少赋值一次,否则编译器将提示:使用了未赋值的out参数;
在被调用函数内,ref引入的参数在返回前不必为其赋初值。
总结:C#中的ref和out提供了值类型按引用进行传递的解决方案,当然引用类型也可以用ref和out修饰,但这样已经失去了意义。因为引用数据类型本来就是传递的引用本身而非值的拷贝。ref和out关键字将告诉编译器,现在传递的是参数的地址而不是参数本身,这和引用类型默认的传递方式是一样的。同时,编译器不允许out和ref之间构成重载,又充分说明out和ref的区别仅是编译器角度的,他们生成的IL代码是一样的。有人或许疑问,和我刚开始学习的时候一样的疑惑:值类型在托管堆中不会分配内存,为什么可以按地址进行传递呢?值类型虽然活在线程的堆栈中,它本身代表的就是数据本身(而区别于引用数据类型本身不代表数据而是指向一个内存引用),但是值类型也有它自己的地址,即指针,现在用ref和out修饰后,传递的就是这个指针,所以可以实现修改后a,b的值真正的交换。这就是ref和out给我们带来的好处。 首先:两者都是按地址传递的,使用后都将改变原来参数的数值。
其次:rel可以把参数的数值传递进函数,但是out是要把参数清空,就是说你无法把一个数值从out传递进去的,out进去后,参数的数值为空,所以你必须初始化一次。这个就是两个的区别,或者说就像有的网友说的,rel是有进有出,out是只出不进。 ref(C# 参考)
ref 关键字使参数按引用传递。其效果是,当控制权传递回调用方法时,在方法中对参数的任何更改都将反映在该变量中。若要使用 ref 参数,则方法定义和调用方法都必须显式使用 ref 关键字。
例如:
class RefExample
{
static void Method(ref int i)
{
i = ;
}
static void Main()
{
int val = ;
Method(ref val);
// val is now 44
}
}
传递到 ref 参数的参数必须最先初始化。这与 out 不同,后者的参数在传递之前不需要显式初始化。
尽管 ref 和 out 在运行时的处理方式不同,但在编译时的处理方式相同。因此,如果一个方法采用 ref 参数,而另一个方法采用 out 参数,则无法重载这两个方法。例如,从编译的角度来看,以下代码中的两个方法是完全相同的,因此将不会编译以下代码:
class CS0663_Example
{
// Compiler error CS0663: "cannot define overloaded
// methods that differ only on ref and out".
public void SampleMethod(ref int i) { }
public void SampleMethod(out int i) { }
}
但是,如果一个方法采用 ref 或 out 参数,而另一个方法不采用这两个参数,则可以进行重载,如下例所示:
class RefOutOverloadExample
{
public void SampleMethod(int i) { }
public void SampleMethod(ref int i) { }
} out(C# 参考)
out 关键字会导致参数通过引用来传递。这与 ref 关键字类似,不同之处在于 ref 要求变量必须在传递之前进行初始化。若要使用 out 参数,方法定义和调用方法都必须显式使用 out 关键字。
例如:
class OutExample
{
static void Method(out int i)
{
i = ;
}
static void Main()
{
int value;
Method(out value);
// value is now 44
}
}
尽管作为 out 参数传递的变量不必在传递之前进行初始化,但需要调用方法以便在方法返回之前赋值。 ref 和 out 关键字在运行时的处理方式不同,但在编译时的处理方式相同。因此,如果一个方法采用 ref 参数,而另一个方法采用 out 参数,则无法重载这两个方法。例如,从编译的角度来看,以下代码中的两个方法是完全相同的,因此将不会编译以下代码:
class CS0663_Example
{
// Compiler error CS0663: "Cannot define overloaded
// methods that differ only on ref and out".
public void SampleMethod(out int i) { }
public void SampleMethod(ref int i) { }
} 但是,如果一个方法采用 ref 或 out 参数,而另一个方法不采用这两类参数,则可以进行重载,如下所示:
class RefOutOverloadExample
{
public void SampleMethod(int i) { }
public void SampleMethod(out int i) { }
}

ref与out之间的区别整理 摘自与望楼http://blog.csdn.net/xiaoning8201/article/details/6893154的更多相关文章

  1. ref与out之间的区别整理

    ref和out都是C#中的关键字,所实现的功能也差不多,都是指定一个参数按照引用传递. 对于编译后的程序而言,它们之间没有任何区别,也就是说它们只有语法区别. 总结起来,他们有如下语法区别: 1.re ...

  2. [转帖] select、poll、epoll之间的区别总结[整理] + 知乎大神解答 https://blog.csdn.net/qq546770908/article/details/53082870 不过图都裂了.

    select.poll.epoll之间的区别总结[整理] + 知乎大神解答 2016年11月08日 15:37:15 阅读数:2569 http://www.cnblogs.com/Anker/p/3 ...

  3. 数组中&a与&a[0]的区别 转载自http://blog.csdn.net/FX677588/article/details/74857473

    在探讨这个问题之前,我们首先来看一道笔试题,如下: [摘自牛客网]下列代码的结果是:(正确答案是 C) main() { int a[5]={1,2,3,4,5}; int *ptr=(int *)( ...

  4. queue_delayed_work和queue_work区别 (转http://blog.csdn.net/dosculler/article/details/7968101)

    queue_delayed_work和queue_work 一.参考文献: 1)http://www.linuxidc.com/Linux/2011-08/41655.htm queue_delaye ...

  5. 抽象类和接口有什么区别---https://blog.csdn.net/csdn_aiyang/article/details/71171886

    https://blog.csdn.net/csdn_aiyang/article/details/71171886 概念]   抽象类.具体类是相对的,并非绝对的.抽象是一种概念性名词,具体是一种可 ...

  6. OpenGL坐标系之间的转换 http://blog.csdn.net/sac761/article/details/52179585

    1. OpenGL 渲染管线 OpenGL渲染管线分为两大部分,模型观测变换(ModelView Transformation)和投影变换(Projection Transformation).做个比 ...

  7. asp.net mvc(模式)和三层架构(BLL、DAL、Model)的联系与区别 转载自:http://blog.csdn.net/luoyeyu1989/article/details/8275866

    首先,MVC和三层架构,是不一样的. 三层架构中,DAL(数据访问层).BLL(业务逻辑层).WEB层各司其职,意在职责分离. MVC是 Model-View-Controller,严格说这三个加起来 ...

  8. 进程 、进程组、会话、控制终端之间的关系 (转载 http://blog.csdn.net/yh1548503342/article/details/41891047)

    一个进程组可以包含多个进程 进程组中的这些进程之间不是孤立的,他们彼此之间或者存在者父子.兄弟关系,或者在功能有相近的联系. 那linux为什么要有进程组呢?其实提供进程组就是方便管理这些进程.假设要 ...

  9. 重载与重写的区别----https://blog.csdn.net/zhu_apollo/article/details/1852542

    重载 overloading        1) 方法重载是让类以统一的方式处理不同类型数据的一种手段.多个同名函数同时存在,具有不同的参数个数/类型.重载是一个类中多态性的一种表现.        ...

随机推荐

  1. Linux安全审计命令

    安全审计 数据分析 capinfos xxx.pcap 产看数据包基本信息 日志分析 who /var/log/wtmp #查看登录用户信息 哈希校验 sha265 文件名 md5sum 文件名 &g ...

  2. iOS开发怎么样做第三方登陆(友盟社会化分享)

    基于前一篇文章   自定义UI后 实现如下代码   即可 //第三方登陆 //    UMSocialSnsPlatform *snsPlatform = [UMSocialSnsPlatformMa ...

  3. Spring MVC集成slf4j-logback

    转自: Spring MVC集成slf4j-logback 1.  Spring MVC集成slf4j-log4j 关于slf4j和log4j的相关介绍和用法,网上有很多文章可供参考,但是关于logb ...

  4. 处理html页面元素工具类(HtmlAgilityPack.dll)的使用

    下载地址:http://htmlagilitypack.codeplex.com/ 1.添加HtmlAgilityPack.dll引用(引用类using HtmlAgilityPack;). 2.简单 ...

  5. KindeEditor图片上传插件用法

    因业务需要找了款插件 KindeEditor编辑器确认挺好用,但无奈技术有限,上传配置不知,故问度娘! 图片上传对于部分新手来说有时候是一件非常头疼的事,今天来分享一下项目中使用到的这个插件Kinde ...

  6. WCF、Web API、WCF REST、Web Service的区别

    Difference between WCF and Web API and WCF REST and Web Service   The .Net framework has a number of ...

  7. 好友与组--ESFramework 4.0 进阶(11)

    大部分分布式通信系统中,都会涉及到客户端之间相互通信.以及需要将客户端进行分组的功能,或者是类似这方面的需求.ESFramework对这一常见的任务内置了强大的支持,包括从客户端到服务端.一直到Pla ...

  8. yii框架中关于控制器中filter过滤器和外部action的使用

    在yii框架中,控制器的过滤器分为执行前和执行后,这里举例是在执行控制器前的过滤. 需要在components/文件夹下定义公共的TestAction.php文件,并且实现run()方法.这个acti ...

  9. Android应用测试性能的工具Emmagee,导出文件格式问题分析

    原文引用自:http://www.open-open.com/lib/view/open1367026451078.html Emmagee是监控指定被测应用在使用过程中占用机器的CPU.内存.流量资 ...

  10. 如何用Navicat for MySQL 将mysql中的数据库导出,导入。

    数据库导出 1.双击要导出的数据库,右键选转储SQL文件...,选择要保存的文件夹. 2.点击开始后,开始导出. 数据库导入 1.新建数据库,数据库的名字必须和导入的数据库文件一致. 2.在新建的数据 ...