浅析class与struct区别
记得以前学C语言老师就讲过struct,那个时候struct主要是用在链表的处理中。后来自己学了C++,才开始接触class,class就不用我介绍了吧。.NET里对struct和class这两个关键字都有支持,刚开始学C#的时候就以为C#保留struct是为了与以前的语言兼容一下,struct只是class的另一种表现形式罢了。在看了《Applied Microsoft .Net Framework Programming》后,才发现struct与class间的关系并不只是那么简单。
class是引用类型,特点:1、内存必须从托管堆分配;2、每个在托管堆中分配的对象有一些与之关联的附加成员必须初始化;3、从托管堆中分配的对象可能会导致垃圾收集。我对引用类型的理解就是个指针。
Struct是值类型,分配在线程的堆栈上,不包含指向实例的指针。就像int、double、char这些值类型一样,也就是他们本身存储了值。
举个非常简单的例子就能说明问题(这个例子来自那本书):
1
using System;
2![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/None.gif)
3
namespace struct与class
4![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
5
//引用类型
6![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
class SomeRef
{public int x;}
7
//值类型
8![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
struct SomeVal
{public int x;}
9![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
10
class Class1
11![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
12
[STAThread]
13
static void Main(string[] args)
14![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
15
SomeRef r1=new SomeRef();
16
SomeVal v1=new SomeVal();
17
r1.x=5;
18
v1.x=5;
19
Console.WriteLine("Before Evaluation:");
20
Console.WriteLine("r1.x="+r1.x);
21
Console.WriteLine("v1.x="+v1.x);
22![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
23
SomeRef r2=r1;
24
SomeVal v2=v1;
25
r1.x=8;
26
v2.x=9;
27![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
28
Console.WriteLine("After Evaluation:");
29
Console.WriteLine("r1.x="+r1.x+";r2.x="+r2.x);
30
Console.WriteLine("v1.x="+v1.x+";v2.x="+v2.x);
31
}
32
}
33
}
34![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/None.gif)
2
![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/None.gif)
3
![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/None.gif)
4
![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](https://www.cnblogs.com/Images/dot.gif)
5
![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
6
![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](https://www.cnblogs.com/Images/dot.gif)
7
![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
8
![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](https://www.cnblogs.com/Images/dot.gif)
9
![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
10
![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
11
![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](https://www.cnblogs.com/Images/dot.gif)
12
![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
13
![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
14
![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](https://www.cnblogs.com/Images/dot.gif)
15
![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
16
![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
17
![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
18
![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
19
![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
20
![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
21
![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
22
![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
23
![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
24
![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
25
![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
26
![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
27
![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
28
![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
29
![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
30
![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
31
![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
32
![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
33
![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
34
![](https://lzcarl.cnblogs.com/Images/OutliningIndicators/None.gif)
结果:
Before Evaluation:
r1.x=5
v1.x=5
After Evaluation:
r1.x=8;r2.x=8
v1.x=5;v2.x=9
很明显,对v2的修改未影响到v1,对r1的修改影响到了r2。
画个图说明一下它们的内存分配:
那保留struct还有什么用呢,既然都用class。说句老实话,我也觉得没什么用,虽然书上说在线程栈上更快,但毕竟没有GC照顾你,object的深拷贝也比较好实现。权当是C#的一个知识点,记住就行了。