引用类型参数使用ref与不使用ref的区别

原创 2011年01月13日 16:27:00

我们都知道:

 

ref关键字使参数按引用传递。其效果是,当控制权传递回调用方法时,在方法中对参数的任何更改都将反映在该变量中。(摘自msdn)。

 

同时我们也可以在msdn上找到这样一段话:

 

按引用传递值类型(如本主题前面所示)是有用的,但是 ref 对于传递引用类型也是很有用的。这允许被调用的方法修改该引用所引用的对象,因为引用本身是按引用来传递的。下面的示例显示出当引用类型作为 ref 参数传递时,可以更改对象本身。

 

理解:不使用ref关键字引用类型的参数传递的是该对象(记为对象A)的引用,即对象A位于托管堆中的地址。而使用ref关键字的引用类型的参数传递的是该对象(记为对象B)引用的引用,即保存对象B位于托管堆中地址的变量(该变量位于堆栈中)的引用。即ref传递的是堆栈地址,而引用(引用类型的引用)传递的是托管堆的地址。当将ref使用在引用类型上,传递的是保存引用类型对象堆地址的栈地址,而不是堆地址。

 

下面用一个例子来对比使用ref和不适用ref的区别

 

源代码:

class Program
    {
        static void Main(string[] args)
        {
            A a1 = new A();
            a1.ID = 1;
            Console.WriteLine(string.Format("Main a1.ID: /t{0}", a1.ID));
            RefCall(ref a1);
            Console.WriteLine(string.Format("Main a1.ID: /t{0}", a1.ID));

            Console.WriteLine();

            A a2 = new A();
            a2.ID = 1;
            Console.WriteLine(string.Format("Main a2.ID: /t{0}", a2.ID));
            Call(a2);
            Console.WriteLine(string.Format("Main a2.ID: /t{0}", a2.ID));

            Console.Read();
        }

        static void RefCall(ref A a)
        {
            a.ID = 2;
            Console.WriteLine(string.Format("RefCall a.ID: /t{0}", a.ID));
            a = new A();
            Console.WriteLine(string.Format("RefCall a.ID: /t{0}", a.ID));
        }

        static void Call(A a)
        {
            a.ID = 3;
            Console.WriteLine(string.Format("Call a.ID: /t{0}", a.ID));
            a = new A();
            Console.WriteLine(string.Format("Call a.ID: /t{0}", a.ID));
        }
    }

    class A
    {
        private int id = 0;
        public int ID
        {
            get { return this.id; }
            set { this.id = value; }
        }
    }

 

运行结果:

Main a1.ID: 1
RefCall a.ID: 2
RefCall a.ID: 0
Main a1.ID: 0

 

Main a2.ID: 1
RefCall a.ID: 3
RefCall a.ID: 0
Main a2.ID: 3

 

通过运行结果我们可以知道使用ref关键字传递参数的方法改变了Main函数中的变量(这里为a1),而不适用ref关键字的方法没有改变Main函数中的变量(这里为a2)。

 

至此我们就应该对引用类型使用和不使用ref关键的区别一目了然了。

C#中参数为引用类型加ref和不加的区别

首先说说两种数据类型:值类型和引用类型的区别值类型包含int、double、char、bool、struct、还有枚举enum, 声明一个值类型的变量会在栈上分块空间用来存储变量的值,如int a=...

C#中关于引用参数ref关键字的使用和本质论

本篇博客主要介绍的是ref关键字的使用和本质: 1.ref关键字的使用 2.ref关键字的本质 1.ref的使用-ref的作用主要是让值类型能够像引用类型一样在方法中进行了值的改变,在方法结束之后,能...

引用传递的参数类型,加不加ref是不同的 .

教科书上说引用传递的参数引用时,加不加ref都可以,都会改变参数原来的值,值传递参数引用时如果想要改变原来的值,必须加ref。以前遇到的大部分情况确实是如此,引用传递类型比如ArrayList,Dat...
  • jstops
  • jstops
  • 2015年12月28日 10:50
  • 78

引用传递的参数类型,加不加ref是不同的

教科书上说引用传递的参数引用时,加不加ref都可以,都会改变参数原来的值,值传递参数引用时如果想要改变原来的值,必须加ref。以前遇到的大部分情况确实是如此,引用传递类型比如ArrayList,Dat...

C#框架阅读笔记--引用参数ref和out区别

引用参数ref和out区别     这两个关键字的区别在于那个方法负责初始化引用对象,如果方法的参数标记为out, 那么调用者不希望在调用方法之前初始化对象,被调用的方法不能读取对象的值,而且被 ...

C#值类型与引用类型、 out 、 ref、 params 参数、函数重载、数组为函数参数或返回值

1、 在C#中方法是将一堆代码进行重用的一种机制; 若调用类中的方法时,若类与Main()函数在一个类中是,类名可以省略,若不在一个类中,类名不可以省略; 2 、 返回值为数组的函数 public ...

C# 下ref和out 参数使用

[csharp]  using System;  using System.Collections.Generic;  using System.Text;    namespace CSh...

在 C# 异步方法中使用 out/ref 参数机制

介绍几种方法,处理 .NET异步方法需要多个返回值的问题。

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

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

oracle存储过程中使用Ref Cursor强类型游标返回结果集

定义类型 定义游标 chuangj
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:引用类型参数使用ref与不使用ref的区别
举报原因:
原因补充:

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