深刻理解C#的传值调用和传引用调用
传值调用和传引用调用是几乎所有主流语言都会涉及到的问题,下面我谈谈我对C#中传值调用和传引用调用的理解。
1. 一般对C#中传值调用和传引用调用的理解
- 如果传递的参数是基元类型(int,float等)或结构体(struct),那么就是传值调用。
- 如果传递的参数是类(class)那么就是传引用调用。
- 如果传递的参数前有ref或者out关键字,那么就是传引用调用。
验证示例的代码如下:
view sourceprint?
01 using System;
02
03 public class ArgsByRefOrValue
04 {
05 public static void Main(string[] args)
06 {
07 // 实验1. 传值调用--基元类型
08 int i = 10;
09 Console.WriteLine("before call ChangeByInt: i = " + i.ToString());
10 ChangeByInt(i);
11 Console.WriteLine("after call ChangeByInt: i = " + i.ToString());
12
13 Console.WriteLine("==============================================");
14 // 实验2. 传值调用--结构体
15 Person_val p_val = new Person_val();
16 p_val.name = "old val name";
17 Console.WriteLine("before call ChangeByStruct: p_val.name = " + p_val.name);
18 ChangeByStruct(p_val);
19 Console.WriteLine("after call ChangeByStruct: p_val.name = " + p_val.name);
20
21 Console.WriteLine("==============================================");
22 // 实验3. 传引用调用--类
23 Person_ref p_ref = new Person_ref();
24 p_ref.name = "old ref name";
25 Console.WriteLine("before call ChangeByClass: p_ref.name = " + p_ref.name);
26 ChangeByClass(p_ref);
27 Console.WriteLine("after call ChangeByClass: p_ref.name = " + p_ref.name);
28
29 Console.WriteLine("==============================================");
30 // 实验4. 传引用调用--利用ref
31 Person_ref p = new Person_ref();
32 p.name = "old ref name";
33 Console.WriteLine("before call ChangeByClassRef: p.name = " + p.name);
34 ChangeByClassRef(ref p);
35 Console.WriteLine("after call ChangeByClassRef: p.name = " + p.name);
36
37 Console.ReadKey(true);
38 }
39
40 static void ChangeByInt(int i)
41 {
42 i = i + 10;
43 Console.WriteLine("when calling ChangeByInt: i = " + i.ToString());
44 }
45
46 static void ChangeByStruct(Person_val p_val)
47 {
48 p_val.name = "new val name";
49 Console.WriteLine("when calling ChangeByStruct: p_val.name = " + p_val.name);
50 }
51
52 static void ChangeByClass(Person_ref p_ref)
53 {
54 p_ref.name = "new ref name";
55 Console.WriteLine("when calling ChangeByClass: p_ref.name = " + p_ref.name);
56 }
57
58 static void ChangeByClassRef(ref Person_ref p)
59 {
60 p.name = "new ref name";
61 Console.WriteLine("when calling ChangeByClassRef: p.name = " + p.name);
62 }
63 }
64
65 public struct Person_val
66 {
67 public string name;
68 }
69
70 public class Person_ref
71 {
72 public string name;
73 }
运行结果如下:
看起来似乎上面代码中实验3和实验4是一样的,即对于类(class)来说,不管加不加ref或out,都是传引用调用。
其实,这只是表面的现象,只要稍微改一下代码,结果就不一样了。
修改上面代码,再增加两个实验。
上一个:C# 动态修改配置文件 (二)
下一个:C#后台线程工作时更新界面的处理方法