从堆栈浅析c#的ref、out关键字
篇外话:老了,是睡不好醒得早的充分条件还是充分必要条件呢?如果是后者,我是不是可以认为,睡不好,是因为我老了。。。。6点多起来纠结这篇文,好歹也是技术博,不能连篇门面都没。。。。。
msdn中对ref关键字的介绍为:ref 关键字使参数按引用传递。其效果是,当控制权传递回调用方法时,在方法中对参数的任何更改都将反映在该变量中。若要使用 ref 参数,则方法定义和调用方法都必须显式使用 ref 关键字。传递到ref 参数的参数必须最先初始化。这与 out 不同,后者的参数在传递之前不需要显式初始化。因为ref和out仅仅是在运行时的处理方式不同,但在编译时的处理方式相同的。这点可以通过反编译的文件可以看出,不赘述。基于此点,本文只单独分析ref关键字,out大同小异,亦不赘述,读者自己构建相同的代码分析可得。
在csdn中有一篇“对于关键字Ref和Out的理解”,原文有点小错,我基于那个文和代码,下面做一定的额外分析。感谢原文作者。先贴代码,然后具体分析。(点击+号展开代码)
1
private void button1_Click(object sender, EventArgs e)2

{3

int[] firstArray =
{1, 2, 3};4
int[] firstArrayCopy = firstArray;5
this.label1.Text = "Test Passing firstArray reference by value";6
this.label1.Text += "\n\nContents of firstArray before calling FirstDouble:\n\t";7

8
for(int i = 0;i < firstArray.Length; i++)9

{10
this.label1.Text += firstArray[i] + " ";11
}12
unsafe13

{14
fixed (int* p = &firstArray[0])15

{};16
}17
18
19
FirstDouble(firstArray);20

21
unsafe22

{23
fixed (int* d = &firstArray[0])24

{ };25
}26

27
this.label1.Text += "\n\nContents of firstArray after calling FirstDouble.\n\t";28
for(int i=0;i < firstArray.Length; i++) 29

{30
this.label1.Text += firstArray[i] + " ";31
}32
if(firstArray == firstArrayCopy)33
this.label1.Text +="\n\nThe references refer to the same array.\n";34
else35
this.label1.Text +="\n\nThe reference refer to different arrays.\n";36

37

38

int[] secondArray =
{1, 2, 3};39
int[] secondArrayCopy = secondArray;40

41
this.label1.Text += "\nTest passing secondArray reference by reference.";42
this.label1.Text += "\n\nContents of secondArray before calling SecondDouble:\n\t";43
for(int i=0;i < secondArray.Length; i++)44

{45
this.label1.Text += secondArray[i] + " ";46
}47

48
unsafe49

{50
fixed (int* q = &secondArray[0])51

{ };52
}53
SecondDouble(ref secondArray);54

55
unsafe56

{57
fixed (int* f = &secondArray[0])58

{ };59
}60
this.label1.Text +="\n\nContents of secondArray after calling SecondDouble:\n\t";61

62
for(int i=0; i < secondArray.Length; i++)63

{64
this.label1.Text += secondArray[i] + " ";65
}66
if(secondArray== secondArrayCopy)67
this.label1.Text += "\n\nThe reference refer to the same array.";68
else69
this.label1.Text += "\n\nThe reference refer to different arrays.";70
this.label1.Text += "\n___________________heshi_________________\nsecondarray\n";71
for(int i = 0;i < secondArray.Length; i++)72

{73
this.label1.Text += secondArray[i] + " ";74
}75

76
this.label1.Text +="\nsecondarraycopy\n";77
for(int i=0;i < secondArray.Length; i++)78

{79
this.label1.Text += secondArrayCopy[i] + " ";80
}81

82
}83
private void FirstDouble(int[] array)84

{85
for(int i = 0;i < array.Length; i++)86

{87
array[i] *= 2; 88
}89
unsafe90

{91
fixed (int* x = &array[0])92

{93
}94
}95
96

97
98

array = new int[]
{11, 12, 13};99

100
unsafe101

{102
fixed (int* y = &array[0])103

{104
}105
} 106
107

108
}109
private void SecondDouble(ref int[] array)110

{111
for(int i=0;i < array.Length; i++)112

{113
array[i] *= 2;114
}115
unsafe116

{117
fixed (int* m = &array[0])118

{119
}120
}121

array = new int[]
{11, 12, 13};122
unsafe123

{124
fixed (int* n = &array[0])125

{126
}127
} 128
}

浙公网安备 33010602011771号