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

总结起来,他们有如下语法区别:

1、ref传进去的参数必须在调用前初始化,out不必,即:
int i;
SomeMethod( ref i );//语法错误
SomeMethod( out i );//通过

2、ref传进去的参数在函数内部可以直接使用,而out不可:
public void SomeMethod(ref int i)
{
   int j=i;//通过
   //...
}
public void SomeMethod(out int i)
{
   int j=i;//语法错误

}

3、ref传进去的参数在函数内部可以不被修改,但out必须在离开函数体前进行赋值。

ref在参数传递之前必须初始化;而out则在传递前不必初始化,且在
...
值类型与引用类型之间的转换过程称为装箱与拆箱。

总结:
应该说,系统对ref的限制是更少一些的。out虽然不要求在调用前一定要初始化,但是其值在函数内部是不可见的,也就是不能使用通过out传进来的值,并且一定要在函数内赋一个值。或者说函数承担初始化这个变量的责任。

下面谈谈ref和out到底有什么区别:

1 关于重载

原则:有out|ref关键字的方法可以与无out和ref关键字的方法构成重载;但如想在out和ref间重载,编译器将提示:不能定义仅在ref和out的上的方法重载

2 关于调用前初始值

原则:ref作为参数的函数在调用前,实参必须赋初始值。否则编译器将提示:使用了未赋值的局部变量;

         
out作为参数的函数在调用前,实参可以不赋初始值。

3 关于在函数内,引入的参数初始值问题

原则:在被调用函数内,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 = 44;

}

static void Main()

{

int val = 0;
       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 = 44;

}

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之间的区别的更多相关文章

  1. Spring中Bean的命名问题(id和name区别)及ref和idref之间的区别

    Spring中Bean的命名 1.每个Bean可以有一个id属性,并可以根据该id在IoC容器中查找该Bean,该id属性值必须在IoC容器中唯一: 2.可以不指定id属性,只指定全限定类名,如: & ...

  2. (转)Spring中Bean的命名问题(id和name区别)及ref和idref之间的区别

    Spring中Bean的命名 1.每个Bean可以有一个id属性,并可以根据该id在IoC容器中查找该Bean,该id属性值必须在IoC容器中唯一: 2.可以不指定id属性,只指定全限定类名,如: & ...

  3. Spring中Bean的命名问题及ref和idref之间的区别

    一直在用Spring,其实对其了解甚少,刚去了解了一下Spring中Bean的命名问题以及ref和idref之间的区别,略作记录,以备后查. Spring中Bean的命名 1.每个Bean可以有一个i ...

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

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

  5. ref与out之间的区别整理 摘自与望楼http://blog.csdn.net/xiaoning8201/article/details/6893154

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

  6. [转] C#中out和ref之间的区别

    gskcc 的原文地址 C#中out和ref之间的区别 首先:两者都是按地址传递的,使用后都将改变原来参数的数值. 其次:ref可以把参数的数值传递进函数,但是out是要把参数清空,就是说你无法把一个 ...

  7. git fetch和git pull之间的区别--转载

    原文地址:http://blog.csdn.net/a19881029/article/details/42245955 git fetch和git pull都可以用来更新本地库,它们之间有什么区别呢 ...

  8. 大数据 --> Spark和Hadoop作业之间的区别

    Spark和Hadoop作业之间的区别 熟悉Hadoop的人应该都知道,用户先编写好一个程序,我们称为Mapreduce程序,一个Mapreduce程序就是一个Job,而一个Job里面可以有一个或多个 ...

  9. select、poll、epoll之间的区别总结

    select.poll.epoll之间的区别总结 05/05. 2014 select,poll,epoll都是IO多路复用的机制.I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪 ...

随机推荐

  1. MarkDown常用语法记录

    目录 1. 斜体和粗体 2. 分级标题 3. 超链接 3.1 行内式(推荐) 3.2 行外式 3.3 自动链接 4. 锚点 5. 列表 5.1无序列表 5.2有序列表 6. 引用 7. 插入图像 8. ...

  2. arm-linux-androideabi-addr2line

    ./arm-linux-androideabi-addr2line -C -f -e libc.so 00040d94

  3. php操作redis简单例子

    <?php //在PHP里操作Redis //Redis就是php的一个功能类 //创建Redis对象 $redis = new Redis(); //链接redis服务器 $redis -&g ...

  4. build.fxbuild打不开 Failed to create the part's controls

    Failed to create the part's controls 以文本形式打开之后,发现编码的地方不是常用编码 将之修改为GBK 然后就可以正常打开了 最后把eclipse中的编码统一设置为 ...

  5. testlink部署与迁移

    几个特殊的文件: 1.D:\xampp\htdocs\testlink\config.inc  安装配置文件,此处需要修改安装目录(g_repositoryPath.log_path) 2.D:\xa ...

  6. Python网络连接

    import appuifw as ui import httplib from os import abort uia=ui.app uin=ui.note uiq=ui.query e32=ui. ...

  7. Unity3d copy gameobject from one scene to another

    scene-copy-game-objects-from-one-scene-to-anotherhttp://forum.unity3d.com/threads/scene-copy-game-ob ...

  8. 【JAVA】【leetcode】【使用堆栈实现后向计算】

    题目:evaluate-reverse-polish-notation 要求: Evaluate the value of an arithmetic expression in Reverse Po ...

  9. 定位 position: absolute & relative

    [position:absolute] 意思是绝对定位,他默认参照浏览器的左上角,配合TOP.RIGHT.BOTTOM.LEFT(下面简称TRBL)进行定位,有以下属性: 1)如果没有TRBL,以父级 ...

  10. Mvc 提交表单的4种方法全程详解

    一,MVC  HtmlHelper方法 Html.BeginForm(actionName,controllerName,method,htmlAttributes){} BeginRouteForm ...