第一章 C# out和ref详解

要想充分理解C# out和ref,必须先明确如下两个概念(对值类型与引用类型掌握比较好的,可以跳过“一、明确两个基本概念”)

一、明确两个基本概念

值类型:

定义:通过值的方式来传递,即实际参数向形式参数传递(关于形参和实参术语,这里不定义)。

存储方式:主要在栈中。

本质:通过值传递,copy副本形式,调用栈的Pop()和Push()方法来实现。

常见类型:int,float,bool,enum,struct,Array等。

值类型例子:

        //主函数
        static void Main(string[] args)
        {
            //定义两个实参n1和n2,并初始化
            int n1 = 10, n2 = 20;
            Console.WriteLine("交换前n1和n2的值");
            Console.WriteLine("n1={0},n2={1}", n1, n2);//n1=10,n2=20
            Swap(n1,n2);
            Console.WriteLine("交换后n1和n2的值");
            Console.WriteLine("n1={0},n2={1}",n1,n2);//n1=10,n2=20
            Console.Read();
        }

        /// <summary>
        /// 交换两个变量的值
        /// </summary>
        /// <param name="n1">形参n1</param>
        /// <param name="n2">形参n2</param>
       static private void Swap(int t1,int t2)
        {
            int temp;
            temp =t1;
            t1 =t2;
            t2 = temp;
        }

分析:以上代码,通过值传递,交换两个变量后,并没有改变n1和n2的值,根本原因是,值传递是通过copy副本形式,不改变原值。图如下:

  1)定义变量n1和n2,并初始化变量,在内存中的表示大致如下( int n1 = 10, n2 = 20;)   

Code调试

在内存中表示

2)执行交换变量方法时

Code调试

在内存中表示

交换详细步骤示意图

引用类型:

定义:通过地址来传递,如c++中的指针。通俗地讲,把地址当作开门的钥匙即可。

存储方式:主要存储在堆中。

本质:通过地址来传递,共享变量,一个改变,所有改变。

常见类型:String,Object等。

code:c++

// Cpplus.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

//主函数
int _tmain(int argc, _TCHAR* argv[])
{
    void Swap(int *x, int *y);
    int n1 = 10, n2 = 20;
    printf("交换前n1和n2的值\n");
    printf("%d,%d\n", n1, n2);
    Swap(&n1,&n2);
    printf("交换后n1和n2的值\n");
    printf("%d,%d",n1,n2);
    getchar();
    return 0;
}
//交换函数
void Swap(int *x, int *y)
{
    int temp = *x;
    *x = *y;
    *y = temp;
}

result:

调试

示意图

二、为什么引入out和ref

由以上分析可知,值传递是无法改变变量的值的,若要像c++一样,改变变量的值,该怎么办?c#引入了out和ref来解决该问题。因此,out和ref均属于引用类型。

二、out详解

一句话概括之:out只进不出。

      //主函数
        static void Main(string[] args)
        {
            int n1, n2;
            Console.WriteLine(GetSum(out n1,out n2));
            Console.Read();

        }
     //out参数
       static public int GetSum(out int numberFirst,out int numberSecond)
        {
            numberFirst = 10;
            numberSecond = 3;
            return numberFirst + numberSecond;
        }

result:

out特点:

1、方法定义和调用方法都必须显示使用out关键字。(如上代码显然易见)

2、out只出不进,即具有清空方法体外参数功能。(如上代码,读者可以任意改变n1和n2的值,只要不改变GetSum()方法体,输出的值均为13)

3、为引用类型。(直接调用而不事先定义n1和n2,编译不通过)

4、同名函数,out不与ref同时存在,可以重载。

//如下两个方法可以重载public void getNumer(int num){}

public void  setTime(out int num){num=10;}

//如下两个方法不能重载
public void getNumer(ref int num){num=10;}public void setTime(out int num){num=10;}

三、ref详解

一句话概括之:有进有出。

     //主函数
        static void Main(string[] args)
        {
            int n1=1, n2=3;
            Console.WriteLine(refGetSum(ref n1,ref n2));
            Console.Read();

        }
      //ref参数
       static public int refGetSum(ref int numberFirst, ref int numberSecond)
       {
           numberFirst = 10;
           numberSecond = 3;
           return numberFirst + numberSecond;
       }

ref特点:

1、方法定义和调用方法都必须显示使用ref关键字。(如上代码显然易见)

2、ref有进有出,即可以把值传入方法体内。(如上代码,读者可以任意改变n1和n2的值)

3、为引用类型。(直接调用而不事先定义n1和n2,编译不通过)

4、同名函数,out不与ref同时存在,可以重载。

四、out与ref异同

主要区别,out只输出yuan‘chuang,ref有进有出。

五、版权

版权申明:本文章为原创,欢迎转载,但必须注明原文地址:http://www.cnblogs.com/wangjiming/p/6169939.html

除此之外,文章不免有瑕疵之处,欢迎大家指出,共同学习共同进步。

时间: 2024-11-03 03:28:28

第一章 C# out和ref详解的相关文章

第四课-第一讲04_01_Linux用户管理命令详解

第四课-第一讲04_01_Linux用户管理命令详解1.useradd [option] USERNAME-u UID(大于500且没使用过的)-c 用户说明,COMMENT-d 家目录 HOME-g GID 基本组ID-G GID,....附加值ID-s 默认shell,指定要用的shell的路径-m(常和-k一起用) 强制指定家目录-M 不创建用户家目录环境变量:PATHHISTSIZESHELL:保持当前用户的默认shell的路径/etc/shells:指定了当前系统可用的安全shell/

“全栈2019”Java第五十七章:多态与构造方法详解

难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第五十七章:多态与构造方法详解 下一章 "全栈2019"Java第五十八章:多态中方法返回类型可以是子类类型 学习小组 加入同步学习小组,共同交流与进步. 方式一:关注头条号Gorhaf,私信"Java学习小组". 方式二:关注公众号Gorhaf,回复"Java

“全栈2019”Java第六十三章:接口与抽象方法详解

难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第六十三章:接口与抽象方法详解 下一章 "全栈2019"Java第六十四章:接口与静态方法详解 学习小组 加入同步学习小组,共同交流与进步. 方式一:关注头条号Gorhaf,私信"Java学习小组". 方式二:关注公众号Gorhaf,回复"Java学习小组&qu

“全栈2019”Java第六十四章:接口与静态方法详解

难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第六十四章:接口与静态方法详解 下一章 "全栈2019"Java第六十五章:接口与默认方法详解 学习小组 加入同步学习小组,共同交流与进步. 方式一:关注头条号Gorhaf,私信"Java学习小组". 方式二:关注公众号Gorhaf,回复"Java学习小组&qu

“全栈2019”Java第八十三章:内部类与接口详解

难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第八十三章:内部类与接口详解 下一章 "全栈2019"Java第八十四章:接口中嵌套接口详解 学习小组 加入同步学习小组,共同交流与进步. 方式一:关注头条号Gorhaf,私信"Java学习小组". 方式二:关注公众号Gorhaf,回复"Java学习小组&quo

“全栈2019”Java第九十六章:抽象局部内部类详解

难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第九十六章:抽象局部内部类详解 下一章 "全栈2019"Java第九十七章:在方法中访问局部内部类成员详解 学习小组 加入同步学习小组,共同交流与进步. 方式一:关注头条号Gorhaf,私信"Java学习小组". 方式二:关注公众号Gorhaf,回复"Java学

“全栈2019”Java多线程第十三章:线程组ThreadGroup详解

难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多线程第十三章:线程组ThreadGroup详解 下一章 "全栈2019"Java多线程第十四章:线程与堆栈详解 学习小组 加入同步学习小组,共同交流与进步. 方式一:关注头条号Gorhaf,私信"Java学习小组". 方式二:关注公众号Gorhaf,回复"Ja

zabbix专题:第九章 zabbix自动发现功能详解

zabbix自动发现功能详解 对Linux有兴趣的朋友加入QQ群:476794643 在线交流 本文防盗链:http://zhang789.blog.51cto.co zabbix自动发现功能详解 网络发现简介 有100台服务器,不想一台台主机去添加,能不能让zabbix自动添加主机呢,当然可以,网络发现便是这个功能,当然前提条件是所有服务器都已经安装了agent或者snmp(其实也可以不用,鉴于我们大部分功能都用agent,所以请安装上agent),server扫描配置好的ip段,自动添加ho

第五章 音频和视频应用详解(第一篇)

---恢复内容开始--- 5.1处理音频 1.使用<video>元素标记 当前<video>标记支持如下三种格式 Ogg:带有Theora视频编码和vorbis音频的Ogg文件 MPEG4:带有H.264视频编码和Acc音频编码的MPEG4文件 WebM:带有Vp8视频编码和Vorbis音频编码的WebM文件 control:供添加播放.暂停和音量控件 <video>标记允许多个"source"元素,"source元素可以链接不同的视频文件