`
hanjiangduzhuo
  • 浏览: 83401 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
最近访客 更多访客>>
社区版块
存档分类
最新评论

ref 关键字的用法

阅读更多

ref 关键字在 C# 中经常使用,但是一直也没有认真考虑过它的确切含义。经常写代码,然而最基本的都还没有搞清楚,真是惭愧呀 :( 以前觉得使用 ref 是传的引用,如果在此方法里面更改参数的值,那此参数对应的变量的值也会被更改。

下面的代码是 MSDN 上的例子:

 1 // cs_ref.cs
 2 using System;
 3 public class MyClass 
 4 {
 5   public static void TestRef(ref char i) 
 6   {
 7     // The value of i will be changed in the calling method
 8     i = 'b';
 9   }
10 
11   public static void TestNoRef(char i) 
12   {
13     // The value of i will be unchanged in the calling method
14     i = 'c';
15   }
16 
17   // This method passes a variable as a ref parameter; the value of the 
18   // variable is changed after control passes back to this method.
19   // The same variable is passed as a value parameter; the value of the
20   // variable is unchanged after control is passed back to this method.
21   public static void Main() 
22   {
23   
24     char i = 'a';    // variable must be initialized
25     TestRef(ref i);  // the arg must be passed as ref
26     Console.WriteLine(i);
27     TestNoRef(i);
28     Console.WriteLine(i);
29   }
30 }

输出结果是:

b
b

在上面的例子中,是使用值类型作为参数的。那如果使用对象作为参数,会是什么样的呢?请看下面的代码:

 1 // cs_object_ref.cs
 2 using System;
 3 
 4 public class MyObject
 5 {
 6   public int Data;
 7 }
 8 
 9 public class MyClass 
10 {
11   public static void TestRef(ref MyObject m) 
12   {
13     // The value of MyObject.Data will be changed in the calling method
14     m.Data = 10;
15   }
16 
17   public static void TestNoRef(MyObject m) 
18   {
19     // The value of MyObject.Data will be unchanged in the calling method
20     m.Data = 20;
21   }
22   
23   public static void TestCreateRef(ref MyObject m) 
24   {
25     m = new MyObject();
26     m.Data = 100;
27   }
28   
29   public static void TestCreateNoRef(MyObject m) 
30   {
31     m = new MyObject();
32     m.Data = 200;
33   }
34 
35   public static void Main() 
36   {
37   
38     MyObject m = new MyObject();
39     m.Data = 1;
40     
41     TestRef(ref m);
42     Console.WriteLine(m.Data);
43     
44     TestNoRef(m);
45     Console.WriteLine(m.Data);
46     
47     TestCreateRef(ref m);
48     Console.WriteLine(m.Data);
49     
50     TestCreateNoRef(m);
51     Console.WriteLine(m.Data);
52   }
53 }

输出结果为:

10
20
100
100

我们可以看到在 TestRef 和 TestNoRef 方法中修改参数的值,相应变量的值都会更改,因为都是传递的引用啊:) 但是在后面 TestCreateRef 和 TestCreateNoRef 两个方法中,它们的结果就不太一样了。

在使用 ref 关键字的方法中重新创建实例的时候,不仅方法中变量的引用被更新(这个当然啦,不然创建实例干嘛呀 :)),而且调用者中变量的引用也被同时更新。将好像是在调用者的范围内使用 new 关键字创建对象一样。

而在不使用 ref 关键字的方法中只是将此方法中的变量的引用更改了,并没有更改调用者变量的引用。也就是说在 TestCreateNoRef 方法中对新创建的变量做任何更改,调用者都不会知道!

分享到:
评论

相关推荐

    Ref和out关键字的区别

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

    C#中ref和out的区别浅析

    在C#中通过使用方法来获取返回值时,通常只能得到一个返回值。因此,当一个方法需要返回多个值的时候,就需要用到ref和out,那么这两个方法区别在哪儿呢? MSDN:  ref 关键字使参数按引用传递。其效果是,当控制权...

    C#中ref,out和params有什么区别

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

    C#中按引用传递与按值传递的区别,以及ref与out关键字的用法详解

    以下是对C#中按引用传递与按值传递的区别,以及ref与out关键字的用法进行了详细的分析介绍,需要的朋友可以过来参考下

    C#编程中使用ref和out关键字来传递数组对象的用法

    主要介绍了C#编程中使用ref和out关键字来传递数组对象的用法,在C#中数组也是对象可以被传递,需要的朋友可以参考下

    前端React中函数式hooks组件中关于ref使用介绍,以及forwardRef 与 useImperativeHand详解

    知识领域:前端 React、函数式Hooks组件、Class类组件技术关键字: ref + createRef + useRef + forwardRef + useImperativeHand内容概要:解决在react中父组件调用子组件中的方法问题,尤其是函数式组件,子组件...

    C#程序设计复习题.doc

    5、使用ref关键字和out关键字都是通过引用传递参数,不同的是ref方式要求实参必须 在传递之前进行__________。而采用out方式时不要求在调用方法前对实参进行____ ______。 6、静态方法只能访问类中的 ________ 字段...

    c#基础系列之ref和out的深入理解

    本文中说的Ref和Out都是引用传递,Ref的重点是把值传给调用方法,Out则是得到调用方法的值,类似于有返回类型的方法返回的值; 在使用两者时一定要注意一下两点,否则编译出现错误 a) ref 变量使用前要先声明同时要...

    自测试卷2.doc13.DataReader对象与DataSet对象有何区别? 14.线程在C#中使用什么类表示,你在什么情况下会考虑程序中使用线程?

    5.如果要将一个方法定义为无返回值类型的方法,则需要使用什么关键字? 6.下列代码中x的输出结果是___________。 private int Add(ref int x, int y) { x = x + y; return x; } static void Main(string[] ...

    基于params,ref,out的参数问题详解

    paramsparams 关键字在方法成员的参数列表中使用,为该方法提供了参数个数可变的能力,它在只能出现一次并且不能在其后再有参数定义(之前可以)。示例: 代码如下:using System;using System.Collections.Generic;...

    string类.doc

    C++string类的总结,关于string的所有资料均可查到。

    理解C#中参数的值和引用以及传递结构和类引用的区别

    若要通过引用传递参数,请使用 ref 或 out 关键字。 下面的示例阐释值与引用参数之间的区别: class Program { static void Main(string[] args) { int arg; // Passing by value. // The value of arg in ...

    c#进行项目设计时可以直接使用资源

    11.c#基础ref和out 12.c#基础二分查找法 13.c#基础数组选择排序 14.c#基础数组冒泡排序 15.c#基础二维数组 16.c#进阶类的设计 17.c#进阶static关键字 18.c#进阶构造方法 19.c#进阶构造方法 20.c#进阶构造方法(静态...

    lor-api:Runeterra FREE CARD API的传奇

    有两种使用数据集的方法,首选的一种是使用获取数据API样式,或仅克隆存储库。 jsDelivr: 向以下链接和选项发出GET请求。 例子 [资源] 小路 资源资源 cards.json 所有卡 卡/[cardCode].json 单卡 keyword....

    C# 7.2中结构体性能问题的解决方案

    in和ref readonly关键字的使用让这个问题出现得更频繁,而readonly结构体提供了一种解决方法。 C#中的结构体通常用于提升性能,减少用于分配和销毁内存的开销。然而,潜在的陷阱限制了它们的使用。C# 7.2增加了一个...

    C#教程语法

    • 程序中不使用#include关键字。程序中的从属关系是象征性的而不是字面上地。这个系统消除了在用不同语言编写的程序间的障碍。例如,Console类可以用另外一种语言编写。 1.2 类型 C#支持两种类型:数据类型和引用...

    C#编程入门

    包括C#中面向对象概念;类,接口,委托等分类;方法,属性,事件等类成员;对象创建,对象成员调用;+,-,=等数十种运算符的使用;ref,out等数十种关键字的使用

    在一小时内学会 C#(txt版本)

    所以如果你不想一个类被继承,你可以对该类使用 sealed 关键字。 复制内容到剪贴板 代码: sealed class CanNotbeTheParent { int a = 5; } unsafe 你可以使用 unsafe 修饰符在 C# 中定义一个不安全上下文。在不...

Global site tag (gtag.js) - Google Analytics