c#中Class和Struct使用与性能的区别
Posted wolf96
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c#中Class和Struct使用与性能的区别相关的知识,希望对你有一定的参考价值。
在Unity中很多已经定义为结构体的数据结构- Vector2, Vector3 和 Vector4
- Rect
- Color和Color32
- Bounds
- Touch
1.Class为引用类型,Struct为值类型
值类型与引用类型的区别这两篇文章讲得很好 http://www.cnblogs.com/tonney/archive/2011/04/28/2032205.htmlhttp://blog.csdn.net/liulong1567/article/details/50678930 虽然我们在.net中的框架类库中,大多是引用类型,但是我们程序员用得最多的还是值类型。
引用类型如:string,Object,class等总是在从托管堆上分配的,C#中new操作符返回对象的内存地址--也就是指向对象数据的内存地址。
以下是值类型与引用类型的表: 从这张图可以看出,class(类)实例化出来的对象,指向了内存堆中分配的空间 struct(结构) 实例化出来的对象 ,是在 内存栈 中分配
所以,值类型和引用类型的区别就是: 1、它们存储的位置不一样 2、如果是引用类型,当两个对象指向同一个地方,修改某一个的时候,其它对象的值会发生改变 当说到类的实例是传引用时,实际过程是,先获取一个指针,它指向对象在内存中的地址,然后传递这个指针。这很重要,因为一个类的实例,实际上可能很大,包含了很多域甚至其他对象。在这种情况下,赋值和传递整个实例可能非常影响性能,这就为什么要用传地址来替代。 说到传值时,实际过程是,对这个变量进行全克隆/拷贝,然后传递这个副本,原始值不变。结构体就是值类型,它是传值的。这意味着,结构体是理想的小型数据结构。
由于引用类型在托管堆上分配,它只会在调用垃圾回收时才被清理。 值类型实在内存栈上分配,这就说明他们很容易被回收,而且不受垃圾回收的影响。
数据类型分隔为值类型和引用类型。值类型要么是堆栈分配的,要么是在结构中以内联方式分配的。引用类型是堆分配的。引用类型和值类型都是从最终的基类 Object 派生出来的。当值类型需要充当对象时,就在堆上分配一个包装(该包装能使值类型看上去像引用对象一样),并且将该值类型的值复制给它。该包装被加上标记,以便系统知道它包含一个值类型。这个进程称为装箱,其反向进程称为取消装箱。装箱和取消装箱能够使任何类型像对象一样进行处理。
2.Class可以继承父类,Struct不可以
所有结构体都默认继承System.ValueType父类,所以不能继承别的父类,ValueType是值类型的基类,详见: https://msdn.microsoft.com/zh-cn/library/system.valuetype(VS.80).aspx3.Struct必须在构造函数对所有变量赋值
结构体中所有变量都必须在构造函数中初始化4.Struct没有默认构造函数
Struct不允许有参数为空的构造函数
5.Struct与class的性能上的优缺点
关于值类型与引用类型的内存可以看这篇文章: https://msdn.microsoft.com/zh-cn/dd365372值类型的实例化之后在内存的大小就是其所有内容物大小,也就是内容物内存越大、占用内存越大,存放在栈中,但是取值更快,不需要GC回收 引用类型把值存放在堆中,引用存在栈中,实例化时要在堆中取值,所以更消耗时间,但是更省内存,因为只用引用指针的大小,需要GC回收
值类型 | 引用类型 | |||
内存 | 大 | 小 | ||
耗时 | 小 | 大 | ||
GC | 小 | 大 | ||
6.Struct类型变量默认不可为空
也就是说,不能写这个语句 struct != null,如果像这样做的话,一定要加上?,为它取值要加上Value,判断是否为空要用HasValue Struct? struct = *****; if(struct.HasValue) struct.Value.***** = ****; 原因参考这篇文章: http://blog.csdn.net/xiaojie_cp/article/details/45892325 值类型后面加问号表示可为空null(Nullable 结构) Nullable是.NET 2.0中新提供的一种用于标明一个值类型是否可以为空的技术。 对于一个类型,如果既可以给它分配一个值,也可以给它分配空引用null(表示没有任何值),我们就说这个类型是可空的。 因此,可空类型可表示一个值,或表示不存在任何值。例如,类似 String 的引用类型就是可空类型,而类似 Int32 的值类型不是可空类型。Nullable 结构支持将值类型扩展为可以为null,但不支持在引用类型上使用,因为引用类型本身就是可空的。 因为值类型的容量只够表示适合于该类型的值,因此它不可为空;值类型没有表示空值所需的额外容量。 例:public int? age;等同 Nullable<int>
7.其他
值类型还有一个特性就是一旦修改值,就会产生一个值类型的副本 引用类型修改值,不会产生副本,但所有有该引用的值都会被修改8.扩充
来自《深入理解C#》值类型很能干,它们不需要垃圾回收,(除非被装箱)不会因类型标识而产生开销,也不需要解引用。
在其他方面,引用类型显得更能干,在传递参数、赋值、将值返回和执行类似的操作时,只需复制4或8字节(要看运行的是是32位还是64位CLR),而不是赋值全部数据。
值类型传给一个方法时,就得复制他的全部数据。
根据性能进行设计之前,需要衡量不同的选择。
类型(不管是类还是结构体),拥有多少方法并不重要,每个实例所占用的内存不会受到影响。(代码本身会消耗内存,但这只会发生一次,而不是每个实例都发生)
-update 2017/8/6
by wolf96 2017/7/19
以上是关于c#中Class和Struct使用与性能的区别的主要内容,如果未能解决你的问题,请参考以下文章