【C#】值类型VS引用类型and现金VS存折

 第一次接触是拆箱和装箱的定义:后来就查了查发现了很多问题,后来就百度了一下,发现了一句话印象特别的深刻:值类型是现金,引用类型是存折。这样把书本上那些生硬的话跟现实生活中常见的事物联系起来了。更直白点儿说:值类型就是现金,要用直接用;引用类型是存折,要用还得先去银行取现。

         下面言归正传:

 一、概念:

1.值类型:
         (1)在栈中分配内存,在声明时初始化才能使用,不能为null。

         (2)超出作用范围系统自动释放内存。

         (3)表示实际的数据

2.引用类型:

         (1)在堆中分配内存,初始化时默认为null。
         (2)通过垃圾回收机制进行回收。

 
 
C#中定义的值类型包括原类型(Sbyte、Byte、Short、Ushort、Int、Uint、Long、Ulong、Char、Float、Double、Bool、Decimal)、枚举(enum)、结构(struct)
 
引用类型包括:类、数组、接口、委托、字符串等。
 
二、 下面用一段代码更加深入的理解区别(此代码为模仿)
 
<span style="font-size:18px;"></span><pre name="code" class="html"><span style="font-size:18px;">Public static class Person
        {
            public string Name { get; set; }
            public int Age { get; set; }
        }
        public  class Marry
        {
            public static void Marryme()
            {
                Person xiaodong = new Person { Name = "XiaoDong", Age = 25 };
                Person dongwife = new Person { Name = "DongWife", Age = 23 };

                int age = xiaodong.Age;
                xiaodong.Age = 22;

                Person guy = dongwife;
                dongwife.Name = "buzhidao";

                Console.WriteLine("xiaodong's age:\t{0}", xiaodong.Age);
                Console.WriteLine(" age'value:\t{0}", age);
                Console.WriteLine(" dongwife'value:\t{0}", dongwife.Name);
                Console.WriteLine(" guy'name:\t{0}", guy.Name);

            }
        }</span>
 
上面这段代码,我们首先创建了一个Person类,包含了Name和Age两个属性,看上面的图片知道,Person类是引用类型,Name也是,但Age则是值类型。接下来我们来看看Marryme方法,其中演示的就是值类型跟引用类型的区别
(1)首先,我们声明了两个Person类的实例对象,xiaodong和dongwife,前面提到过,这两个对象都被分配在堆上,而xiaodong和dongwife本身其实只是对象所在内存区域的起始地址引用,换句话说就是指向这里的指针。我们声明对象实例时也顺便分别进行了初始化,首先我们看,xiaodongl对象的值类型成员,我们赋值为25岁,dongwife的Name属性,我们赋值为“Dongwife”。
(2)我们声明一个值类型变量age,直接在初始化时把xiaodong的Age值赋给它,显然,age的值就是25了。但这个时候xiaodong想让自己的年龄改成22岁,刚够法定结婚年龄。然后我们又声明了一个引用类型的guy对象,初始化时就把Dongwife赋给它,他的名字叫“buzhidao”。接下来我们来分别答应出这几个变量的值,看看有什么差别。


细心的人会发现以下几个问题

1、为什么我们改了xiaodong.Age的值,age没跟着变,改了dongwife.Name的值,guru.Name却跟着变了呢?

这就是值类型和引用类型的区别。我们声明age值类型变量,并将xiaodong.Age赋给它,编译器在栈上分配了一块空间,然后把xiaodong.Age的值填进去,仅此而已,二者并无任何牵连,就像复印机一样,只是把xiaodong.Age的值拷贝给age了。而引用类型不一样,我们在声明guy的时候把dongwife赋给它,前面说过,引用类型包含的是只想堆上数据区域地址的引用,其实就是把dongwife的引用也赋给guy了。

为了更好地说明两种类型之间的区别,借用如下的表格来说明。              

问题

值类型

引用类型

内存分配地点

分配在栈中

分配在堆中

效率

效率高,不需要地址转换

效率低,需要进行地址转换

内存回收

使用完后,立即回收

使用完后,不是立即回收,等待GC回收

赋值操作

进行复制,创建一个同值新对象

只是对原有对象的引用

函数参数与返回值

是对象的复制

原有对象的引用,并不产生新的对象

类型扩展

不易扩展

容易扩展,方便与类型扩展

性能上也会有区别的。既然一个是直接操作内存,另一个则多一步先解析引用地址,那么显然很多时候值类型会减小系统性能开销。但“很多时候”不代表“所有时候”,有些时候还得量力而为,例如需要大量进行函数参数传递或返回的时候,老是这样进行字段拷贝,其实反而会降低应用程序性能。另外,如果实例会被频繁地用于Hashtable或者ArrayList之类的集合中,这些类会对其中的值类型变量进行装箱操作,这也会导致额外的内存分配和内存拷贝操作,从应用程序性能方面来看,其实也不划算。

 
:1、GC(Garbage Collector,垃圾回收器)是一种自动回收内存的机制,释放已经不再使用的对象的内存空间。
         2、堆和堆栈区别:
 
堆和堆栈是两个不同的概念,在内存中的存储位置也不相同,
 
堆一般用于存储可变长度的数据,如字符串类型;
 

堆栈则用于存储固定长度的数据,如整型类型的数据int(每个int变量占用四个字节)。由数据存储的位置可以得知,当把一个值变量赋给另一个值变量时,会在堆栈中保存两个完全相同的值;而把一个引用变量赋给另一个引用变量,则会在堆栈中保存对同一个堆位置的两个引用,即在堆栈中保存的是同一个堆的地址。在进行数据操作时,对于值类型,由于每个变量都有自己的值,因此对一个变量的操作不会影响到其它变量;对于引用类型的变量,对一个变量的数据进行操作就是对这个变量在堆中的数据进行操作,如果两个引用类型的变量引用同一个对象,实际含义就是它们在堆栈中保存的堆的地址相同,因此对一个变量的操作就会影响到引用同一个对象的另一个变量。


小结:这篇文章文字比较多,需要一点一点的推敲。因为之前没有学过堆和栈所以理解起来比较吃力,不过通过总结还是多少懂了那么一点了。如果有更好的理解这方面的知识,希望可以一起讨论。

 

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值