C# 值类型、引用类型区别;ref,out区别

什么是值类型和引用类型

什么是值类型
所有的结构都是抽象类型System.ValueType的直接派生类,而System.ValueType本身又是直接从System.Object派生的。根据定义所知,所有的值类型都必须从System.ValueType派生,所有的枚举都从System.Enum抽象类派生,而后者又从System.ValueType派生。
所有的值类型都是隐式密封的(sealed),目的是防止其他任何类型从值类型进行派生。

什么是引用类型
在c#中所有的类都是引用类型,包括接口

分配、回收区别:
值类型通常被人们称为轻量级的类型,因为在大多数情况下,值类型的实例都分配在线程栈中,因此它不受垃圾回收的控制,缓解了托管堆中的压力,减少了应用程序的垃圾回收的次数,提高性能。

引用类型的实例都分配在托管堆上,c#中***new***操作符会返回一个内存地址指向当前的对象。所以当你在创建个一个引用类型实例的时候,你必须要考虑以下问题:
1.内存是在托管堆上分配的
2.在分配每一个对象时都会包含一些额外的成员(类型对象指针,同步块索引),这些成员必须初始化
3.对象中的其他字节总是设为零
4.在分配对象时,可能会进行一次垃圾回收操作(如果托管堆上的内存不够分配一次对象时)

性能区别:
在设计一个应用程序时,如果都是应用类型,那么应用程序的性能将显著下降,因为这会加大托管堆的压力,增加垃圾回收的次数。
虽然值类型是一个轻量级的类型,但是如果大量的使用值类型的话,也会有损应用程序的性能(例如下面要讲的装箱和拆箱操作,传递实例较大的值类型,或者返回较大的值类型实例)。
由于值类型实例的值是自己本身,而引用类型的实例的值是一个引用,所以如果将一个值类型的变量赋值给另一个值类型的变量,会执行一次逐字段的复制,将引用类型的变量赋值给另一个引用类型的变量时,只需要复制内存地址,所以在对大对象进行赋值时要避免使用值类型。
例如:
1 class SomRef
2 {
3 public int x;
4 }
5 struct SomeVal {
6 public int x;
7 }
8 class Program {
9 static void ValueTypeDemo() {
10 SomRef r1 = new SomRef();//在堆上分配
11 SomeVal v1 = new SomeVal();//在栈上分配
12 r1.x = 5;//提领指针
13 v1.x = 5;//在栈上修改
14 SomRef r2 = r1;//只复制引用(指针)
15 SomeVal v2 = v1;//在栈上分配并复制成员
16 }
17 }

这也显示了class与struct的区别,昨天面试的时候面试官也正好问到这个问题。
1.struct更适合看成是一个数据结构的实现体,class更适合看成是一个对象的实现体。
struct没有继承,没有封装,要说封装只有初步封装。而class把数据,接口可以以三种类型封装,private,public,protected;还可以继承和派生。
2.正如上面所说,分配的位置不同,一个在线程栈上,一个在托管堆上
3.class实例由垃圾回收机制来保证内存的回收处理,而struct变量使用完后立即自动解除内存分配
4.作为参数传递时,class变量以按址方式传递,而struct变量是以按值方式传递的

值类型和引用类型常见误区:
1.引用类型分配在托管堆上,值类型分配在线程栈上:其实这种说法的前半部分是对的,后半部分是错的。因为变量的值在它声明的位置存储的,所以假如某一个引用类型中有一个值类型的变量, 那么该变量的值总是和该引用类型的对象的其它数据在一起,也就是分配在堆上。(只有局部变量(方法内部声明的变量)和方法的参数在栈上)

2.结构是轻量级的类:这种错误的信息主要是因为有人认为值类型不应该有方法或者其它有意义的行为-它们应该作为简单的数据转移来使用,所以很多人分不清DateTime到底是值类型还是引用类型。(结论:DateTime是值类型,因为DateTime是结构体,而结构体继承自System.ValueType,属于值类型)

3.对象在c#中默认的是用引用传递的:其实在调用方法的时候,参数值(对象的一个引用)是以传值得方式传递的,如果你想以引用方式传递的话,可以使用ref或者out关键字。

ref、out

ref和out是C#开发中经常使用的关键字,所以作为一个.NET开发,必须知道如何使用这两个关键字.

1、相同点

ref和out都是按地址传递,使用后都将改变原来参数的数值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值