c#中Class和Struct使用与性能的区别

来源:互联网 发布:go语言并发编程实战 编辑:程序博客网 时间:2024/06/07 14:40

1.Class为引用类型,Struct为值类型

值类型与引用类型的区别这两篇文章讲得很好
h t t p : / / w w w .c   n b lo   g s . c o m /t o n n e y / a r c h   i v e/ 2 0 1 1 / 0 4  / 28   / 20   3 2  2 05  .  html
 
  h tt p : / / b lo g . c s d n .n e t / li u l o ng 1 5 6 7/    a r ti c l    e/ d e t ai   l s /5 0 6 7 8 93 0 
虽然我们在.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).aspx
 
 
 

3.Struct必须在构造函数对所有变量赋值

结构体中所有变量都必须在构造函数中初始化
 

4.Struct没有默认构造函数

 
Struct不允许有参数为空的构造函数
 

5.Struct与class的性能上的优缺点

关于值类型与引用类型的内存可以看这篇文章:h   t t p s  : / /m   s d n .m i c ro s o f   t .c o m / z h- c n / d d3 6 5  3 72 
 
值类型的实例化之后在内存的大小就是其所有内容物大小,也就是内容物内存越大、占用内存越大,存放在栈中,但是取值更快,不需要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,但不支持在引用类型上使用,因为引用类型本身就是可空的。
因为值类型的容量只够表示适合于该类型的值,因此它不可为空;值类型没有表示空值所需的额外容量。
原创粉丝点击