zoukankan      html  css  js  c++  java
  • [转载]实际举例C#引用类型和值类型的区别

    http://www.cnblogs.com/coolbeibei/archive/2009/03/23/1419706.html

    实际举例C#引用类型和值类型的区别

        我们都知道,c#的两大数据类型分别为值类型和引用类型。很多人或许闭着眼睛都能说出值类型包括简单类型、结构体类型和枚举类型,引用类型包括自定义类、数组、接口、委托等,但是当被问及到二者之间的联系和区别,什么时候用struct什么时候用class时,就常常混淆不清了。为此,了解值类型和引用类型的本质差异就变的很有必要了。

    1. 值类型直接存储其值,变量本身就包含了其实例数据,而引用类型保存的只是实例数据的内存引用。因此,一个值类型变量就永远不会影响到其他的值类型变量,而两个引用类型变量则很有可能指向同一地址,从而发生相互影响。
    2. 从内存分配上来看,值类型通常分配在线程的堆栈上,作用域结束时,所占空间自行释放,效率高,无需进行地址转换,而引用类型通常分配在托管堆上,由GC来控制其回收,需要进行地址转换,效率降低,这也正是c#需要定义两种数据类型的原因之一。
    3. 值类型均隐式派生自System.ValueType,而System.ValueType又直接派生于System.Object,每种值类型均有一个隐式的默认构造函数来初始化该类型的默认值,注意所有的值类型都是密封(sealed)的,所以无法派生出新的值类型。而且System.ValueType本身是一个类类型,而不是值类型,因为它重写了objectEquals()方法,所以对值类型将按照实例的值来比较,而不是比较引用地址。
    4. C# 的统一类型系统,使得值类型可以转化为对象来处理,这就是常说的装箱和拆箱。由于装拆箱需要装建全新对象或做强制类型转换,这些操作所需时间和运算要远远大于赋值操作,因此不提倡使用它,同时也要尽量避免隐式装拆箱的发生。

    注:栈是操作系统分配的一个连续的内存区域,用于快速访问数据。因为值类型的容量是已知的,因此它可存储在栈上。而托管堆是CLR在应用程序启动时为应用程序预留的一块连续内存区,是用于动态内存分配的内存区,引用类型的容量只有到运行时才能确定,所有用堆来存储引用类型。

    C#的两种数据类型延伸之一--嵌套类型的内存分配

        对于引用类型嵌套值类型,以及值类型嵌套引用类型的情况下,内存分配可以根据以下两条规律来判断:

         引用类型始终部署在托管堆上;

         值类型总是分配在它声明的地方:作为字段时,跟随其所属的对象存储;作为局部变量时,存储在栈上。

    C#的两种数据类型延伸之二--string类型

        string是一个很有意思的引用类型,为什么说它很有意思呢?因为它表现了很多值类型的特点。请看一下代码示例:

    示例1

    string str1 = "abc";

    string str2 = str1;

    str1 = "123";

    Console.WriteLine(str2);

    示例2(msdn上的例子)

    string a = "hello";

    string b = "h";

    // Append to contents of 'b'

    b += "ello";

    Console.WriteLine(a == b);

    示例1的输出结果是abc,改变str1的值对str2没有影响。

    示例2的输出结果是True

        这样的结果会使我们误以为string就是值类型。其实不然,示例1str1 = "123"语句编译器私底下创建了一个新的字符串对象来保存新的字符序列"123",也就是此str1已非彼str1了,“此”str1的值的改变也就不能影响“彼”str1的值了,当然str2的值也就不会改变了。实质上str1 = "123"str1=new string("123")的简写,它的每一次赋值都会抛掉原来的对象而生成一个新的字符串对象,分配新的内存空间,因此string是不可改变的。如果要创建可修改的字符串,可使用stringbuilder以获得更好的性能。至于示例2是因为为了方便比较字符串的值重定义了string的运算符== !=

    C#的两种数据类型延伸之三--structclass 

        classstruct的语法基本相同,从声明到使用,都很相似。但是struct的约束要比class多,理论上,struct能做到的class都能做到,但class能做到的stuct却不一定做的到,也就是说struct都能被class所代替。那么为什么还要使用struct呢?存在即是合理的,struct在很多方面有着性能优势。让我们看看它们的主要区别在哪里?

    • 数据类型不一样,struct是值类型,class是引用类型,因此它们具有所有值类型和引用类型之间的差异。由于堆栈的执行效率要比堆的执行效率高,但是堆栈资源却很有限,不适合处理逻辑复杂的大对象,因此struct常用来处理作为基类型对待的小对象,而class来处理某个商业逻辑。
    • 从继承性来看,struct既不能继承也不能被继承,但是可以实现接口,而Class就可以完全扩展了。
    • 内部结构有区别,struct只能添加带参的构造函数,不能使用abstractprotected等修饰符,不能初始化实例字段,但是值得注意的是,struct可以重写System.Object3个虚方法,Equals()ToString()GetHashTable()Class没有这些限制。

    比较structclass的不同,可以得出以下几条structclass的使用原则:

    1 在表示诸如点、矩形等主要用来存储数据的轻量级对象时,首选struct

    2 在表示数据量大、逻辑复杂的大对象时,首选class

    3 在表现抽象和多级别的对象层次时,class是最佳选择

    做个快乐的自己。
  • 相关阅读:
    Neko's loop HDU-6444(网络赛1007)
    Parameters
    SETLOCAL
    RD / RMDIR Command
    devenv 命令用法
    Cannot determine the location of the VS Common Tools folder.
    'DEVENV' is not recognized as an internal or external command,
    How to change Visual Studio default environment setting
    error signing assembly unknown error
    What is the Xcopy Command?:
  • 原文地址:https://www.cnblogs.com/Jessy/p/2114086.html
Copyright © 2011-2022 走看看