关于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#中方法参数 ref 与 out 的区别

方法中参数的类型有三种 in型参数 in型参数通过值传递的方式将数值传入方法中。即我们在Java中常见的方法 ref型参数 该种类型的参数传递变量地址给方法(引用传递),传递前变量必须初始化。 ...
  • jl1134069094
  • jl1134069094
  • 2016年01月13日 17:25
  • 1008

C#中Out和Ref参数修饰符

在编程过程中对于函数之间的参数的传递一般分为两种:传值和传地址。下面为大家分析一下。  传值     比如你又一份文档,如果采用传值的话,相当于我复制了一份,因此我对我这份文档的修改都不会影响...
  • ZHOUCHAOQIANG
  • ZHOUCHAOQIANG
  • 2014年10月02日 14:31
  • 2901

C#中in,out,ref的作用和区别

ref和out的区别在C# 中,既可以通过值也可以通过引用传递参数。通过引用传递参数允许函数成员更改参数的值,并保持该更改。若要通过引用传递参数, 可使用ref或out关键字。ref和out这两个关键...
  • jadeflute
  • jadeflute
  • 2010年01月20日 22:13
  • 23284

在C#中 ref和out的区别

在C# 中,既可以通过值也可以通过引用传递参数。通过引用传递参数允许函数成员更改参数的值,并保持该更改。若要通过引用传递参数, 可使用ref或out关键字。ref和out这两个关键字都能够提供相似的功...
  • unity_http
  • unity_http
  • 2016年07月15日 20:36
  • 1434

C# ref 和 out ,params关键字的用法

C# ref,out,params 的用法。
  • mydad353193052
  • mydad353193052
  • 2015年08月29日 22:25
  • 805

【Lua】访问C#中的属性和方法-特殊情况-带有out和ref关键字

using System; using LuaInterface; namespace myLua { class MainClass { public string name = "Ocea...
  • sinat_20559947
  • sinat_20559947
  • 2015年08月28日 23:46
  • 3711

C#的out参数和ref参数

刚学C#的时候看过out参数和ref参数的用法,但是一直没有根据实际项目做过
  • u010771437
  • u010771437
  • 2014年11月12日 19:22
  • 631

C#中ref和out参数使用时需要注意的问题

C#方法中的ref和out      ref        通常我们向方法中传递的是值.方法获得的是这些值的一个拷贝,然后使用这些拷贝,当方法运行完毕后,这些拷贝将被丢弃,而原来的值不将受到影响...
  • zzp_403184692
  • zzp_403184692
  • 2012年10月20日 10:10
  • 1584

C#带ref和out的反射使用

摘自 C# TextBox 扩展方法数据验证  这篇文章推荐阅读 public static TResult GetValue(this TextBox textBox, Actio...
  • tvvbbb
  • tvvbbb
  • 2015年10月20日 14:02
  • 1538

c# ref out 区别 比较 汇总

ref(C# 参考) Visual Studio 2015 其他版本   ref 关键字会导致参数通过引用传递,而不是通过值传递。 通过引用传递的效果...
  • hejisan
  • hejisan
  • 2016年07月06日 00:05
  • 706
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:关于C#中的ref和out参数的说明
举报原因:
原因补充:

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