C#:out和ref的用法

out为了输出一个新的值,因此参数必须在方法返回值之前明确赋值;

ref为了改变已有的值,因此参数必须在方法调用之前明确赋值。

 

一、值类型和引用类型

 

C# 中的类型一共分为两类,一类是值类型(Value Type),一类是引用类型(Reference Type)。

值类型包括结构体(struct)和枚举(enum)。 
引用类型包括类(class)、接口(interface)、委托(delegate)、数组(array)等。

常见的简单类型如short、int、long、float、double、byte、char等其本质上都是结构体,对应struct System.Int16、System.Int32、System.Int64、System.Single、System.Double、Syetem.Byte、System.Char,因此它们都是值类型。但string和object例外,它们本质上是类,对应class System.String和System.Object,所以它们是引用类型。

 

1.值类型

值类型变量本身保存了该类型的全部数据,当声明一个值类型的变量时,该变量会被分配到栈(Stack)上。

2. 引用类型

引用类型变量本身保存的是位于堆(Heap)上的该类型的实例的内存地址,并不包含数据。当声明一个引用类型变量时,该变量会被分配到栈上。如果仅仅只是声明这样一个变量,由于在堆上还没有创建该类型的实例,因此,变量值为null,意思是不指向任何类型实例(堆上的对象)。对于变量的类型声明,用于限制此变量可以保存的类型。

 

二、值传递和引用传递  

 

C#中方法的参数传递默认的是值传递,引用传递和输出传递需要在参数类型前面对应加上ref、out限制符。

值传递参数(就是方法体内部)是原变量(就是方法体外部)的拷贝副本,值传递参数和原变量的内存地址不同,因此方法中对值传递参数的修改不会改变原变量。

引用传递参数是原变量的指针,引用传递参数和原变量的内存地址相同,相应的方法中对引用传递参数的修改会改变原变量。

1.当方法的参数为传值参数时,即参数前没有ref和out关键词。

a.若参数为值类型,进入方法体的参数实际上是外部变量的一个副本,对值参数的操作永远不会影响变量的值。

b.若参数为引用类型,进入方法体的参数实际上是外部变量的一个副本,不过参数和变量存储的都是一个地址,且是同一个地址。换句话说,他们引用的是同一个对象,因此,在方法体内部对参数做的改变会直接影响到变量(实际工作中,基本上不会这样去干)。另一种情况,在方法体内部,对该参数进行重新的地址赋值,比如parameter=new Class(),进行这个操作,实际上是把一个新的类型实例的地址赋值给了我们的参数。在这种情况下,对参数的修改不会影响外部的变量。(实际工作中,基本上也不会这样去干)

2.当方法的参数为引用参数时,即参数前有reft关键词。引用形参并不创建新的存储位置。引用形参表示的存储位置,恰是在方法调用中作为实参给出的那个变量所代表的存储位置。

总结一下,方法体外的变量是否变化了,分为五种情况:

1.如果参数是值类型,且无ref,则变量不变;

2.如果参数是值类型,且有ref,则变量改变;

3.如果参数是引用类型,且无ref,且在方法体内,对参数进行了新对象赋值,而不是属性更改,则变量不变。

4.如果参数是引用类型,且无ref,且在方法体内,对参数进行了属性更改,则变量改变。

5.如果参数是引用类型,且有ref,则不管方法体内对参数做了什么操作,新对象赋值或者属性更改,变量都会变。

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值