ref 关键字的用法
2005-06-16 23:13
253 查看
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 }
输出结果是:
在上面的例子中,是使用值类型作为参数的。那如果使用对象作为参数,会是什么样的呢?请看下面的代码:
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 }
输出结果为:
我们可以看到在 TestRef 和 TestNoRef 方法中修改参数的值,相应变量的值都会更改,因为都是传递的引用啊:) 但是在后面 TestCreateRef 和 TestCreateNoRef 两个方法中,它们的结果就不太一样了。
在使用 ref 关键字的方法中重新创建实例的时候,不仅方法中变量的引用被更新(这个当然啦,不然创建实例干嘛呀 :)),而且调用者中变量的引用也被同时更新。将好像是在调用者的范围内使用 new 关键字创建对象一样。
而在不使用 ref 关键字的方法中只是将此方法中的变量的引用更改了,并没有更改调用者变量的引用。也就是说在 TestCreateNoRef 方法中对新创建的变量做任何更改,调用者都不会知道!
下面的代码是 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 方法中对新创建的变量做任何更改,调用者都不会知道!
相关文章推荐
- C#中按引用传递与按值传递的区别,以及ref与out关键字的用法详解
- ref out 关键字用法与区别详解
- C#编程中使用ref和out关键字来传递数组对象的用法
- C# 关键字params的用法 以及C# ref与out区别
- ref 和 out关键字的用法
- C# out、ref关键字的用法和区别
- ref out 关键字用法与区别详解
- ref和out关键字的用法
- C#关键字params, ref, out的用法
- ref和out关键字的用法与区别
- C#参数修饰符(关键字out,ref,params),可选参数
- Java中this和super关键字的用法
- C#的new关键字的几种用法
- Java关键字用法及区别
- 关键字struct的用法
- C语言中const关键字的用法
- Asp.net中params关键字的用法
- Java中instanceof关键字用法
- C++ 第六课:C/C++关键字及其用法
- C/C++ const关键字用法总结