原文: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();

    }

}

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

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

  1. .NET 基础一步步一幕幕[out、ref、params]

    out.ref.params out: 如果你在一个方法中,返回多个相同类型的值的时候,可以考虑返回一个数组. 但是,如果返回多个不同类型的值的时候,返回数组就不行了,那么这个时候, 我们可以考虑使用 ...

  2. out和ref详解

    要想充分理解C# out和ref,必须先明确如下两个概念(对值类型与引用类型掌握比较好的,可以跳过"一.明确两个基本概念") 一.明确两个基本概念 值类型: 定义:通过值的方式来传 ...

  3. c#编程基础之ref、out参数

    引例: 先看这个源码,函数传递后由于传递的是副本所以真正的值并没有改变. 源码如下: using System; using System.Collections.Generic; using Sys ...

  4. C#中out和ref之间的区别【转】

    首先:两者都是按地址传递的,使用后都将改变原来参数的数值. 其次:ref可以把参数的数值传递进函数,但是out是要把参数清空,就是说你无法把一个数值从out传递进去的,out进去后,参数的数值为空,所 ...

  5. 通过一个实例重新认识引用类型,值类型,数组,堆栈,ref

    昨天在写代码时候遇到了一个问题,百思不得其解,感觉颠覆了自己对C#基础知识的认知,因为具体的情境涉及公司代码不便放出,我在这里举个例子,先上整个测试所有的代码,然后一一讲解我的思考过程: using ...

  6. 图解C#的值类型,引用类型,栈,堆,ref,out

    C# 的类型系统可分为两种类型,一是值类型,一是引用类型,这个每个C#程序员都了解.还有托管堆,栈,ref,out等等概念也是每个C#程序员都会接触到的概念,也是C#程序员面试经常考到的知识,随便搜搜 ...

  7. 异步方法不能使用ref和out的解决方法

    异常处理汇总-后端系列:http://www.cnblogs.com/dunitian/p/4523006.html 应用场景==>后端现在都是用异步方法,那么分页是必不可少的,于是就有了这个问 ...

  8. [C#]浅析ref、out参数

    转载:http://www.cnblogs.com/vd630/p/4601919.html#top 按引用传递的参数算是C#与很多其他语言相比的一大特色,想要深入理解这一概念应该说不是一件容易的事, ...

  9. C#基础-out与ref字段

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Cons ...

  10. C# out ref 重载

    今天看极客学院wiki时候看到了out,ref的介绍,之前对这个知识点没有深刻认识,所以就写了个小测试看了下,瞬间明白了. using System; using System.Collections ...

随机推荐

  1. C++辛格尔顿

    设计模式是编程的焦点.经常在面试时进行审查,Singleton模式是最简单的.最常见的.大部分的主模式.所以大部分的采访是测试考试的Singleton设计模式. 以下我们就来看看单例模式怎样实现(C+ ...

  2. 重操JS旧业第十弹:闭包

    闭包是js最难理解,也是最蛋疼的一个名词,仿佛只可意会不可言传一样,有人说闭包说白了就是函数嵌套,也有人说闭包就是函数能够访问函数外部的变量,而内部的外部访问不了: 貌似都非常有道理,其实仔细想来只不 ...

  3. overflow:hidden与position:absolute

    在做一个下拉框的动画效果中遇到了这个bug,记录一下. 在写下拉框的动画的时候,一般我们的做法都是把下拉框的外盒子设为overflow:hidden,然后设下外层盒子高度,之后通过js慢慢的改变高度从 ...

  4. 前端javascript框架之BackboneJS学习笔记

    <!DOCTYPE html><html><head><meta charset="utf-8"><script src=&q ...

  5. 美国企业人事喜欢考的3道.Net经典笔试题

    1..求以下表达式的值,写出您想到的一种或几种实现方法: 1-2+3-4+……+m 答: int Num = this.TextBox1.Text.ToString() ; int Sum = 0 ; ...

  6. 通过程序预览Office文档

    我承认,标题是夸大了,就是为了吸引注意力.这里只有Word文档和Excel文档的预览代码. Word://此部分来源:http://princed.mblogger.cn/posts/11885.as ...

  7. C#分析URL参数获取参数和值得对应列表

    原文: C#分析URL参数获取参数和值得对应列表 /// <summary> /// 分析url链接,返回参数集合 /// </summary> /// <param n ...

  8. Windows 8 动手实验系列教程 实验7:磁贴和通知

    动手实验 实验7:磁贴和通知 2012年9月 简介 磁贴是Windows应用商店应用用户体验的重要元素.当应用程序被安装后,它的磁贴将在Windows 8开始屏幕被创建.该磁贴(称为主磁贴)作为启动应 ...

  9. 配置BeanUtils包,同时也是对导入第三包的步骤说明

    BeanUtils是由Apache公司开发的针对操作JavaBean的工具包. 对于JavaBean,简单的来说,就是要有一个空参的构造器和对属性的getXXX方法和setXXX方法. 在由JDK提供 ...

  10. mfc menu用法一

    #define IDM_NEW 0x1002#define IDM_EXIT 0x1003#define IDM_HELP 0x1004#define IDM_ABOUT 0x1005 hMenu = ...