关于C#中的ref和out参数的说明

原创 2007年09月26日 21:43:00

看下面的例子:

using system;
class test
{
  static void swap(ref int x, ref int y)
{
int temp = x;
x = y;
y = temp;
}
static void swap(int x,int y)
{
int temp = x;
x = y;
y = temp;
}
static void main()
{
int i = 1, j = 2;
swap(ref i, ref j);
console.writeline("i = {0}, j = {1}", i, j);
swap(i,j);
console.writeline("i = {0}, j = {1}", i, j);
}
}

程序经编译后执行输出:

i = 2, j = 1
i = 2, j = 1

这是csdn的一篇帖子上的例子.其实如果放在一起,并不能很容易的看出使用ref和不使用ref的区别.
分开看,就很明显了.
使用ref:

using system;
class test
{
static void swap(ref int x, ref int y)
{
int temp = x;
x = y;
y = temp;
}
static void main()
{
int i = 1, j = 2;
swap(ref i, ref j);
console.writeline("i = {0}, j = {1}", i, j);
}
}

程序经编译后执行输出:

i = 2, j = 1

不使用:

using system;
class test
{
static void swap(int x,int y)
{
  int temp = x;
  x = y;
  y = temp;
}
static void main()
{
  int i = 1, j = 2;
  swap(i,j);
  console.writeline("i = {0}, j = {1}", i, j);
}
程序经编译后执行输出:

i = 1, j = 2;

比较这两个里子很明显,使用了ref关键字的函数调用以后,i和j的值变化了.而没有使用ref的却没有变,为什么呢?

请看下面这段话:

方法的参数是个值得特别注意的地方。方法的参数传递有四种类型:传值(by value),传址(by reference),输出参数(by output),数组参数(by array)。传值参数无需额外的修饰符,传址参数需要修饰符ref,输出参数需要修饰符out,数组参数需要修饰符params。传值参数在方法调用过程中如果改变了参数的值,那么传入方法的参数在方法调用完成以后并不因此而改变,而是保留原来传入时的值。传址参数恰恰相反,如果方法调用过程改变了参数的值,那么传入方法的参数在调用完成以后也随之改变。实际上从名称上我们可以清楚地看出两者的含义--传值参数传递的是调用参数的一份拷贝,而传址参数传递的是调用参数的内存地址,该参数在方法内外指向的是同一个存储位置。

所以我们可以看出,平时我们写的函数参数是传值参数(传值参数无需额外的修饰符),不论他是值类型还是引用类型.你可以试这个例子(这个例子是对"不论他是值类型还是引用类型"这句话,):

using system;
class test
{
static void swap(string x,string y)
{
string temp = x;
x = y;
y = temp;
}
static void main()
{
  string i = "1", j = "2";
  swap(i,j);
  console.writeline("i = {0}, j = {1}", i, j);
}
}
程序经编译后执行输出:
i = "1", j = "2";
注意:string类型是引用类型.
i,j的值并没有改变,说明引用类型作为函数参数时,只要不加ref或者out,那他仍然是传值参数(我一直以为值类型作为函数参数时是传值参数,而引用类型作为函数参数时是传址参数).
.net框架程序设计(修订版)上有这样一句话:ref和out的区别是参数的初始化和参数返回,
可是这里说out是输出参数,那加out是传址参数吗?要不,怎么也会变呢(应该也是吧,可能他只是一个名字,可以理解成输出参数也是传址参数)?

using system;
class test
{
static void swap(out int x, out int y)
{
   int temp = x;
   x = y;
   y = temp;
}
static void main()
{
  int i = 1, j = 2;
  swap(out i, out j);
  console.writeline("i = {0}, j = {1}", i, j);
}
}
程序经编译后执行输出:
i = 2, j = 1
总结:传值参数传递的是调用参数的一份拷贝,而传址参数传递的是调用参数的内存地址,该参数在方法内外指向的是同一个存储位置.
这句话可以这样说更加明白:传值参数传递的是调用参数的拷贝的地址,该参数在方法内外指向的不是是同一个存储位置,而传址参数传递的是调用参数的内存地址,该参数在方法内外指向的是同一个存储位置,
 

【C#基础】方法及其调用、构造方法、out与ref参数及其返回值、方法重载、静态方法等简单介绍

一、方法及其调用 1、方法介绍: 1)功能:用来复用代码。当我们在一个程序中反复地写同样的代码,一般情况下,我们可以把需要重复写的代码定义在一个方法中,用的时候只需要调用就行了。 格式:[访问修...

C#方法的参数关键字:ref、out、params

using System;   namespace 方法的参数传递机制 {       class Method     {            // 值参数(Value P...

【C#基础】方法及其调用、构造方法、out与ref参数及其返回值、方法重载、静态方法等简单介绍

一、方法及其调用 1、方法介绍: 1)功能:用来复用代码。当我们在一个程序中反复地写同样的代码,一般情况下,我们可以把需要重复写的代码定义在一个方法中,用的时候只需要调用就行了。 格式:[访问修...
  • qly2046
  • qly2046
  • 2013年12月28日 09:58
  • 2682

C#中方法参数 ref 与 out 的区别

方法中参数的类型有三种 in型参数 in型参数通过值传递的方式将数值传入方法中。即我们在Java中常见的方法 ref型参数 该种类型的参数传递变量地址给方法(引用传递),传递前变量必须初始化。 ...

C# 参数关键字(params,ref,out)

参数关键字决定了方法中参数的引用形式: 1.Params

C# 参考之方法参数关键字:params、ref及out

C# 参考之方法参数关键字:params、ref及out 如果在为方法声明参数时未使用 ref 或 out,则该参数可以具有关联的值。可以在方法中更改该值,但当控制传递回调用过程时,不会保留更改...

C# 参考之方法参数关键字:params、ref及out

总结: ref和out都对函数参数采用引用传递形式——不管是值类型参数还是引用类型参数,并且定义函数和调用函数时都必须显示生命该参数为ref/out形式。两者都可以使函数传回多个结果。 两者区别:...

浅谈C#中的ref和out参数

很多初学者(甚至是工作一定时间的开发人员),在遇到ref或者out参数时,总会有点“晕乎乎”或者疑惑,也不知道到底该在啥时候,啥场景下使用ref或者out参数。 本文将通过实例和说明,给大家详细讲解...

C#返回多个参数 ref及out

out 关键字会导致参数通过引用来传递。这与 ref 关键字类似,不同之处在于 ref 要求变量必须在传递之前进行初始化。若要使用 out 参数,方法定义和调用方法都必须显式使用 out 关键字。例如...

C#学习:函数的ref、out参数

函数参数默认是值传递的,也就是“复制一份”,通过函数的处理对数值本身并没有影响,如果函数想对数值本身产生影响就需要使用相应的参数。 ref必须先初始化,因为是引用,所以必须先“有”,才能引用。使用r...
  • lissdy
  • lissdy
  • 2012年03月30日 14:19
  • 3887
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:关于C#中的ref和out参数的说明
举报原因:
原因补充:

(最多只允许输入30个字)