C#关于ref与out的总结

原文:C#关于ref与out的总结

 
首先大概说下函数调用的过程,首先为被调用函数分配存储空间(分为代码区和变量区)之后将调用函数传递过来的变量压栈,然后逐一弹栈进行处理,之后进行运算,将需要返回的变量压栈,然后释放存储空间,返回调用函数,继续执行下面的代码。

 
所以在这里就有一个问题,如果我们想要把在被函数中对参数值的修改传回给调用函数怎么办(除了我们可以用return返回一个执行结果)。

 
在c语言中提供了指针变量,我们可以灵活的运用指针型变量进行参数地址的互相传递,并实现了对同一存储空间的变量的操作。这样当调用函数的时候,在被调用函数中对参数的修改就会直接操作调用函数变量的存储空间,这样就得到了保存。

 
在c++中取缔了指针变量,因为它是类型不安全的,容易引起系统的崩溃。取而代之的是引用,所谓引用就是当我们调用函数的时候,编译器会将调用函数的变量名重命名为调用函数的变量名,这样我们在被调用函数中对变量的操作,就是直接对调用函数的变量操作,这样就得到了保存。

 
在C#中同样使用了引用。今天特别记录下C#中提供了两个,一个是ref,还有一个是out。这两个引用是有区别的,按照C#中的说法:ref叫做引用参数,要传递值并原地修改它(也就是在相同的内存位置),用引用参数就很方便。因为传递了一个变量给该方法(不仅仅是它的值),这里调用被调用函数的时候变量必须被初始化。

out叫做输出参数,传递参数可以把它设作一个输出参数。一个输出参数仅用于从方法传递回一个结果。它和引用参数的另一个区别在于:调用者不必先初始化变量才调用方法。(我的理解这里其实就是实现多个return,返回多个运行结果)

 

e.g:

1> 在此例中,在调用方(Main 方法)中声明数组 theArray,并在
FillArray
方法中初始化此数组。然后将数组元素返回调用方并显示。

class TestOut
{
   static void
FillArray(out int[] arr)
    {
       // Initialize the array:
       
arr = new int[5] { 1, 2, 3, 4, 5 };
    }

   static void
Main()
    {
       int[] theArray; // Initialization is not required

       // Pass the array to the callee using
out:
       
FillArray(out theArray);

       // Display the array
elements:
       
System.Console.WriteLine("Array
elements are:");
       for (int i = 0; i < theArray.Length;
i++)
       
{
           
System.Console.Write(theArray[i] + " ");
       
}

       // Keep the console window open in debug
mode.
       
System.Console.WriteLine("Press
any key to exit.");
       
System.Console.ReadKey();
    }
}
   

 

2> 在此例中,在调用方(Main 方法)中初始化数组 theArray,并通过使用
ref 参数将其传递给 FillArray 方法。在
FillArray
方法中更新某些数组元素。然后将数组元素返回调用方并显示。
class TestRef
{
   static void
FillArray(ref int[] arr)
    {
       // Create the array on
demand:
       if (arr == null)
       
{
           
arr = new int[10];
       
}
       // Fill the array:
       
arr[0] = 1111;
       
arr[4] = 5555;
    }

   static void
Main()
    {
       // Initialize the array:
       int[] theArray = { 1, 2, 3, 4, 5
};

       // Pass the array using
ref:
       
FillArray(ref theArray);

       // Display the updated
array:
       
System.Console.WriteLine("Array
elements are:");
       for (int i = 0; i < theArray.Length;
i++)
       
{
           
System.Console.Write(theArray[i] + " ");
       
}

       // Keep the console window open in debug
mode.
       
System.Console.WriteLine("Press
any key to exit.");
       
System.Console.ReadKey();
    }
}
   

特此记录,感谢论坛上的帖子及相关文章。

时间: 2024-10-18 16:49:47

C#关于ref与out的总结的相关文章

关于ref、out和params参数的理解

using System; namespace TestCS{ /// <summary> /// Class1 的摘要说明. /// 本代码演示了ref,out和params关键字在函数参数传递中的作用 /// </summary> class Class1 {  /// <summary>  /// 应用程序的主入口点.  /// </summary>  [STAThread]  static void Main(string[] args)  {   

C#中ref和out的使用小结

ref是传递参数的地址,out是返回值,两者有一定的相同之处,不过也有不同点. 使用ref前必须对变量赋值,out不用. out的函数会清空变量,即使变量已经赋值也不行,退出函数时所有out引用的变量都要赋值,ref引用的可以修改,也可以不修改. 区别可以参看下面的代码: using System;class TestApp{ static void outTest(out int x, out int y) {//离开这个函数前,必须对x和y赋值,否则会报错. //y = x; //上面这行会

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

问题 昨天写了个关于socket接收udp包的程序,调用了socket.ReceiveFrom方法,发现了一个c#中关于ref和out参数传递时的问题,这里提出来和大家共同探讨一下,首先声明,下面的结论都是本人推测,还没有得到任何定论,若有错误请大家指正. 首先,ReceiveFrom方法的原型为 public int ReceiveFrom(byte[], ref EndPoint); 有一个为ref的EndPoint参数,用它来返回收到包的源地址信息,ref的语义是传引用,即对所传引用的修改

如何使用REF CURSOR处理Oracle的结果集

Oracle提供REF CURSOR,通过该功能可以实现在程序间传递结果集的功能,利用REF CURSOR也可以实现BULK SQL,从而提高SQL性能. 使用scott用户的emp表实现以下测试案例: SQL> desc emp Name Null? Type ----------------------------------------- -------- ---------------------------- EMPNO NOT NULL NUMBER(4) ENAME VARCHAR

Oracle 10g Release2新功能之Ref Cursor

Ref Cursor就是我们定义在服务器端的结果集的reference. 当我们打开一个Ref Cursor的时候,没有任何的数据返回到客户端,相反,数据在服务器上的地址将会被返回到客户端.这样用户就可以自己决定什么时间和以那种方式通过Ref Cursor去取数据. 在以前版本的ODP.NET中,我们可以通过Ref Cursor取数据,但是我们不能把Ref Cursor作为一个Input参数传递给PL/SQL的存储过程和存储函数.但是在Oracle Database 10g Release2,我

输出参数out和引用参数ref区别

使用ref的一段代码 using System; class M { public void F(ref int i) { i=3; } } class Test { int i=0; //要作为引用参数传递的变量必须明确赋值 static void Main() { //不能把int i=0;放在这里赋值,会报错说Test不包含i定义. Test t=new Test(); Console.WriteLine("the value of i is:{0}",t.i); M mm=ne

理解C#的Ref和Out关键字

类型介绍 在几乎所有的OOP语言中,都存在2种类型的值. 值类型 引用类型 以C#为例:其值类型为sbyte,byte,char,short,ushort,int,uint,long和ulong,float和double,当然还有decimal和bool.而引用类型则是string和object. 我想说的 我想说的就是--Ref和Out把我弄糊涂的原因是,当时没有认真的去分析它对不同类型所做出的不同的动作. 对于值类型. 使用了Ref和Out的效果就几乎和C中使用了指针变量一样.它能够让你直接

C#中的ref关键字

最近有人问到 ref 关键字的正确用法,下面我们来举例说明.其实要更好的理解 ref 关键字,结合 C++ 代码更加容易一些.另外在开始我们的例子之前,需要提前说明几点: C# 中的数据有两种类型:引用类型(reference types)和值类型(value types). 简单类型(包括int, long, double等)和结构(structs)都是值类型,而其他的类都是引用类型. 简单类型在传值的时候会做复制操作,而引用类型只是传递引用,就像 C++ 中的指针一样. 注意 structs

C#中ref和out使用小结

ref是传递参数的地址,out是返回值,两者有一定的相同之处,不过也有不同点. 使用ref前必须对变量赋值,out不用. out的函数会清空变量,即使变量已经赋值也不行,退出函数时所有out引用的变量都要赋值,ref引用的可以修改,也可以不修改. 区别可以参看下面的代码: using System; class TestApp { static void outTest(out int x, out int y) {//离开这个函数前,必须对x和y赋值,否则会报错. //y = x; //上面这

解析.net中ref和out的实质

可能是.net中的value type和reference type的关系遇到给函数传递参数的情况时, 在我们的脑海里就会浮现按值和按引用传递的概念.如果看见下面这个函数(代码1)我 们就会条件反射似的说要给参数加上ref才能使函数内部修改参数的值. //代码1 void Change(int a, int b) { int tmp = a; a = b; b = tmp } ok,那继续看下面这个代码 //代码2 void Change2(object o) { o = new object(