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

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

1、ref传进去的参数必须在调用前初始化,out不必 
int i;
SomeMethod( ref i );// 语法错误
SomeMethod( out i );// 通过
2、ref传进去的参数在函数内部可以直接使用,而out不可(除非在函数体内部,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作为参数的函数在调用前,实参可以不赋初始值。如果out实参在函数调用之前已经初始化了,在函数内部还是不可见的,相当于屏蔽了out的初值

3 关于函数内部使用问题:
ref传进去的参数在函数内部可以直接使用,

而out不可(除非在函数体内部,out参数在使用之前赋值):

4 关于函数返回时的问题
在被调用函数内,ref引入的参数在返回前不必为其赋初值。
在被调用函数内,out引入的参数在返回前至少赋值一次,否则编译器将提示:使用了未赋值的out参数;

总结: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) { }
}

————————————————
本文为CSDN博主「HawkJony」的原创文章!
原文链接:https://blog.csdn.net/qiaoquan3/article/details/51201398

C#——ref和out的区别相关推荐

  1. ref和out的区别

    ref和out的区别在C# 中,既可以通过值也可以通过引用传递参数.通过引用传递参数允许函数成员更改参数的值,并保持该更改.若要通过引用传递参数, 可使用ref或out关键字.ref和out这两个关键 ...

  2. C#中关键字ref与out的区别(转)

    C#中关键字ref与out的区别(转) 在C#中,ref与out是很特殊的两个关键字.使用它们,可以使参数按照引用来传递. 总的来说,通常我们向方法中传递的是值.方法获得的是这些值的一个拷贝,然后使用 ...

  3. C# 中 ref 和out 的区别

    out 参数前必须先为其赋值,即必须由被调用方为其赋值. class TestOut {static void FillArray(out int[] arr){// Initialize the a ...

  4. vue3 - ref和reactive的区别

    文章搬运自wx60d4764eb475e 的vue3中ref和reactive的区别(系列六) 1. ref和reactive区别:     如果在template里使用的是ref类型的数据, 那么V ...

  5. c#中ref和out的区别

    c#中ref和out的区别: 1,ref必须初始化,out不用初始化. 2,ref参数的值被传递到ref参数,out不能被传递. 注意: 1,属性不是变量,不能作为ref参数传递. 2,ref类似于c ...

  6. 【ref 和 reactive的区别】

    ref 和 reactive的区别 两者概念 ref函数:定义一个响应式的数据(主要针对基础类型数据) 方法:引入 ref 函数,const xxx = ref(initValue) 模板中读取数据: ...

  7. ref与out的区别

    前一段时间老用ref与out 感觉他们的效果差不多,就去网上查了一下他们的区别,网上说的概念性的东西太多了,后来通过自己的摸索发现他们有一个规律 ref: 在引用方法之外必须赋初值 static vo ...

  8. C#中的Params、ref、out的区别

    C# Params params params 关键字可以指定在参数数目可变处采用参数的方法参数. 在方法声明中的 params 关键字之后不允许任何其他参数,并且在方法声明中只允许一个 params ...

  9. .net程序员的盲点(一):参数修饰符ref,out ,params的区别

    C#中有三个关键字-ref,out ,params,虽然本人不喜欢这三个关键字,因为它们疑似破坏面向对象特性.但是既然m$把融入在c#体系中,那么我们就来认识一下参数修饰符ref,out ,param ...

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

    C#中有三个关键字-ref,out ,params,虽然本人不喜欢这三个关键字,因为它们疑似破坏面向对象特性.但是既然m$把融入在c#体系中,那么我们就来认识一下参数修饰符ref,out ,param ...

最新文章

  1. python快速入门第3版 数据_Python 快速入门 第3版
  2. ElasticSearch最全详细使用教程:入门、索引管理、映射详解
  3. .net知识和学习方法系列(三)CSharp中控件台的输入输出
  4. 181219每日一句
  5. qt编写mysql导出excel_Qt编写数据导出到Excel及Pdf和打印数据
  6. 万字详解OpenDRIVE文件
  7. DW个人网站制作成品 简单个人静态HTML网页设计作品 DIV布局个人介绍网页模板代码
  8. 迪普Web应用防火墙产品线
  9. 社交仅发送图片和视频 -设计测试用例
  10. CDR插件开发之Addon插件006 - 初体验:通过C#代码用外挂方式操作CDR中的对象
  11. 2022数字化工地智慧防疫系统助力工地疫情防控实现人员、施工安全闭环管理
  12. 交换机telnet远程登陆配置
  13. [源码解析] 深度学习流水线并行 PipeDream(6)--- 1F1B策略
  14. 微信公众平台对接C#-普通消息接收
  15. 原来Oracle也不喜欢“蜀黍”
  16. lol哪个服务器能玩无限火力,《lol》2021无限火力时间表公告 无限火力什么时候开放...
  17. ASM 系列详细教程-02-ASM 整体概览
  18. 三年时间做到年薪百万,推荐明哥的职场心得
  19. Python之一键生成二维码
  20. python列表转字节_Python3中内置类型bytes和str用法及byte和string之间各种编码转换,python--列表,元组,字符串互相转换...

热门文章

  1. CTF【每日一题20160613】
  2. python 学习汇总1:文件读写 tcy
  3. .Net应用程序 参照的组合没有安装在您的系统中。 HRESULT: 0x800736B3
  4. 打开网页 doctype html,HTML: !DOCTYPE 声明
  5. 今日揭秘:在淘宝上,如何让宝贝秒卡首屏?
  6. 宅米网性能优化实践——初创互联网公司的野蛮成长
  7. 使用《高德导航》,和林志玲郭德纲亲密“互动”
  8. led软件2014年_2014年重要的软件开发发展
  9. 天津理工大学计算机科学与技术专业分数线,天津理工大学计算机科学与技术专业2016年在天津理科高考录取最低分数线...
  10. java org.apache.http_org.apache.http jar包下载-org.apache.http.jar包下载 --pc6下载站