C# 奇怪的值类型方法调用
🏷️ C#
创建一个 Point
类型,拥有 x
和 y
两个私有变量,一个 Change
方法改变 xy
的值,一个重写的 ToString
方法.
csharp
using System;
namespace StructSample
{
class Program
{
static void Main(string args)
{
Point p1 = new Point(1, 1);
Console.WriteLine(p1); // ( 1, 1 )
p1.Change(2, 2);
Console.WriteLine(p1); // ( 2, 2 )
Object o = p1;
Console.WriteLine(o); // ( 2, 2 )
((Point)o).Change(3, 3);
Console.WriteLine(o); // ( 2, 2 )
Console.ReadLine();
}
}
struct Point
{
private int m_x, m_y;
public Point(int x, int y)
{
m_x = x;
m_y = y;
}
public void Change(int x, int y)
{
m_x = x;
m_y = y;
}
public override string ToString()
{
return String.Format("( {0}, {1} )", m_x, m_y);
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
前面 3 次的输出都很正常,第四次输出跟预想的就不一样了,虽然调用了 Change(3, 3)
,但输出仍为 ( 2, 2 )
。
原因还在于值类型的装箱和拆箱。看一下第二次调用 Change
的代码:
csharp
((Point)o).Change(3, 3);
1
因为 Object
类型没有 Change
方法,所以 o
必须显示转换为 Point
型才能调用 Change
方法。
这里会发生一次拆箱,将 o
拆箱后放入栈中,然后调用 Change
方法改变栈中的值,执行结束后栈中的值变为 ( 3, 3)
。
Change
方法结束后,栈中的值并不会再次装箱,而且该值也不会再被引用到,会立即被系统回收。
堆中 o
变量引用的值由于没有发生变更,所以打印的结果仍然为 ( 2, 2)
。