C# ref和out总结
C# 中ref 与 out 总结
参数的传递一般分为两种:一种是“值传递”即:传递实参的拷贝,既然是拷贝那么在函数中对这个形参所作的任何动作都不会反映到原来的实参中。另外一种是“引用传递”即:传递实参的地址(形参和实参指向同一块内存地址),那么在函数中对形参所作的任何改变都要反映到原来的实参中。
在C#中实现“引用传递”的两种方式为:ref 和 out。当然这两种方式也有他们的不同,下面将逐步讲解他们的不同之处。
- 使用ref关键字进行“引用传递”时,传入的实参必须先被初始化,这就像C和C++中的指针一样,一定要先给它赋值(让它指向一个指定的内存位置),要不然它不一定会指向内存的哪里,这样很危险,不允许。而使用out关键字进行“引用传递”时,传入的实参不必先初始化。如下面的例子所示:
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5
6namespace RefAndOut
7{
8 class RefAndOutTesting
9 {
10 static void Main(string[] args)
11 {
12 int x;
13 int y;
14 OutTest(out x, out y);
15 Console.WriteLine(string.Format("x = {0}, y = {1}", x, y));
16
17 int a = 100;
18 int b = 200;
19 RefTest(ref a, ref b);
20 Console.WriteLine(string.Format("a = {0}, y = {1}", a, b));
21 }
23 //out参数在使用前不必初始化
24 public static void OutTest(out int first, out int second)
25 {
27 first = 1;
28 second = 2;
29 }
30 //ref参数在使用前必须初始化
31 public static void RefTest(ref int first, ref int second)
32 {
33 first = 1111;
34 second = 2222;
35 }
36 }
37} - 虽然使用out关键字进行“引用传递”时,传入的实参不必先初始化,但是在函数中一定要先对参数进行初始化,之后再使用。因为:在使用out参数的时候,程序首先将out的实参(形参)置空,(因此实质上实参先初始化了对此函数也没有用)然后再对参数进行相应的操作;由于置空了,所以在离开该函数之前必须完成参数的初始化(即使你不对参数做任何操作),要不然该参数的指针又不知道该指向何处了。假如变化一下上面的OutTest函数:
1 public static void OutTest(out int first, out int second)
2 {
3 first = second;
4 //first = 1;
5 //second = 2;
6 }便会提示你:Use of unassigned out parmeter 'second'。即使你先初始化实参再去调用也会出现同样的错误(原因就是out先对参数进行清空操作)
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5
6 namespace OutAndRef
7 {
8 class Program
9 {
10 static void Main(string[] args)
11 {
12 //out变量在使用之前不必进行显示的赋值
13 int x = 1111;
14 int y = 2222;
15 OutTest(out x, out y);
16 Console.WriteLine("x = {0}, y = {1}", x, y);
17 }
18
20 public static void OutTest(out int first, out int second)
21 {
22 //离开这个函数前,必须对first和second赋值,否则会报错。
23 first = second;
24 //上面这行会报错,因为使用了out后,first和second都清空了,需要重新赋值,即使调用函数前赋过值也不行
25 first = 1;
26 second = 2;
27 }
29 }
31 }
32 - 因此上面的两点可以总结为:ref有出有进,out有出没进。
 - 使用ref和out进行“引用传递”,在定义方法和调用方法时,都要在参数前加ref和out关键字,以满足匹配。
 - 由于属性是方法,不是变量;而指针是变量。所以属性都不可以作为ref和out参数传递。如果在上面的RefAndOutTesting类中声明两个属性,传递给RefTest和OutTest方法中,则会出错!
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5
6 namespace RefAndOut
7 {
8 class RefAndOutTesting
9 {
10 //属性(是方法,不是变量)所以不可以作为ref和out参数
11 public static int firstNumber
12 {
13 get;
14 set;
15 }
16 public static int secondNumber
17 {
18 get;
19 set;
20 }
21
22 //字段可以作为ref和out参数
23 public static int myNumber;
24 public static int yourNumber;
25
26 static void Main(string[] args)
27 {
28 //正确
29 OutTest(out myNumber, out yourNumber);
30 Console.WriteLine( "myNumber = {0}, yourNumber = {1}", myNumber, yourNumber);
31 RefTest(ref myNumber, ref yourNumber);
32 Console.WriteLine( "myNumber = {0}, yourNumber = {1}", myNumber, yourNumber);
33
34 //错误
35 OutTest(out firstNumber, out secondNumber);
36 Console.WriteLine("firstNumber = {0}, secondNumber = {1}", firstNumber, secondNumber);
37 RefTest(ref firstNumber, ref secondNumber);
38 Console.WriteLine("firstNumber = {0}, secondNumber = {1}", firstNumber, secondNumber);
45 }
46 }
47 } 
C# ref和out总结的更多相关文章
- .NET 基础一步步一幕幕[out、ref、params]
		
out.ref.params out: 如果你在一个方法中,返回多个相同类型的值的时候,可以考虑返回一个数组. 但是,如果返回多个不同类型的值的时候,返回数组就不行了,那么这个时候, 我们可以考虑使用 ...
 - out和ref详解
		
要想充分理解C# out和ref,必须先明确如下两个概念(对值类型与引用类型掌握比较好的,可以跳过"一.明确两个基本概念") 一.明确两个基本概念 值类型: 定义:通过值的方式来传 ...
 - c#编程基础之ref、out参数
		
引例: 先看这个源码,函数传递后由于传递的是副本所以真正的值并没有改变. 源码如下: using System; using System.Collections.Generic; using Sys ...
 - C#中out和ref之间的区别【转】
		
首先:两者都是按地址传递的,使用后都将改变原来参数的数值. 其次:ref可以把参数的数值传递进函数,但是out是要把参数清空,就是说你无法把一个数值从out传递进去的,out进去后,参数的数值为空,所 ...
 - 通过一个实例重新认识引用类型,值类型,数组,堆栈,ref
		
昨天在写代码时候遇到了一个问题,百思不得其解,感觉颠覆了自己对C#基础知识的认知,因为具体的情境涉及公司代码不便放出,我在这里举个例子,先上整个测试所有的代码,然后一一讲解我的思考过程: using ...
 - 图解C#的值类型,引用类型,栈,堆,ref,out
		
C# 的类型系统可分为两种类型,一是值类型,一是引用类型,这个每个C#程序员都了解.还有托管堆,栈,ref,out等等概念也是每个C#程序员都会接触到的概念,也是C#程序员面试经常考到的知识,随便搜搜 ...
 - 异步方法不能使用ref和out的解决方法
		
异常处理汇总-后端系列:http://www.cnblogs.com/dunitian/p/4523006.html 应用场景==>后端现在都是用异步方法,那么分页是必不可少的,于是就有了这个问 ...
 - [C#]浅析ref、out参数
		
转载:http://www.cnblogs.com/vd630/p/4601919.html#top 按引用传递的参数算是C#与很多其他语言相比的一大特色,想要深入理解这一概念应该说不是一件容易的事, ...
 - C#基础-out与ref字段
		
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Cons ...
 - C# out ref  重载
		
今天看极客学院wiki时候看到了out,ref的介绍,之前对这个知识点没有深刻认识,所以就写了个小测试看了下,瞬间明白了. using System; using System.Collections ...
 
随机推荐
- sql模糊查询,解除绑定的单号
			
--610007570320-610007571319 1000张 delete from (select t.* from (select t1.bill_code, t1.bind_code, t ...
 - python015 Python3 函数
			
Python3 函数函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段.函数能提高应用的模块性,和代码的重复利用率.你已经知道Python提供了许多内建函数,比如print().但你也可 ...
 - oracle 恢复中的switch datafile all是什么意思
			
使用rman进行恢复时,如果使用了set name修改文件路径,那么恢复后,控制文件里面的信息是没有修改该的,如果要同步控制文件的信息那么就需要使用 switch datafile allall这个可 ...
 - [BZOJ3052][UOJ#58][WC2013]糖果公园
			
[BZOJ3052][UOJ#58][WC2013]糖果公园 试题描述 Candyland 有一座糖果公园,公园里不仅有美丽的风景.好玩的游乐项目,还有许多免费糖果的发放点,这引来了许多贪吃的小朋友来 ...
 - hdu  4710
			
#include<stdio.h> #include<math.h> __int64 min(__int64 a,__int64 b) { return a<b?a:b; ...
 - 【bzoj1042】[HAOI2008]硬币购物-递推与动规-容斥原理
			
硬币购物 硬币购物一共有4种硬币.面值分别为c1,c2,c3,c4.某人去商店买东西,去了tot次.每次带di枚ci硬币,买si的价值的东西.请问每次有多少种付款方法. Input 第一行 c1,c2 ...
 - http的N种请求
			
GET通过请求URI得到资源 POST,用于添加新的内容 PUT用于修改某个内容 DELETE,删除某个内容 CONNECT,用于代理进行传输,如使用SSL OPTIONS询问可以执行哪些方法 PAT ...
 - [Bzoj3131][Sdoi2013]淘金(数位dp)(优先队列)
			
3131: [Sdoi2013]淘金 Time Limit: 30 Sec Memory Limit: 256 MBSubmit: 847 Solved: 423[Submit][Status][ ...
 - Spring教程:tutorialspoint-spring
			
来自turorialspoint的Spring教程(英文),官网:https://www.tutorialspoint.com/spring/index.htm 这个教程在国内已经被翻译成中文(不过是 ...
 - Java获取Linux系统cpu使用率
			
原文:http://www.open-open.com/code/view/1426152165201 import java.io.BufferedReader; import java.io.Fi ...