第二遍看这本书,决定记录一下加深印象。

值类型可以存储在堆和栈上,它是局部变量时存储在栈上,如果值类型是作为类的一个属性,那么就会存储在堆上;

引用类型有两块内存,一块存储引用地址(栈上),一块存储实际的对象(堆上)。

1,基元类型

  什么事基元类型?基元类型是直接映射到FrameWork类库(FCL)中存在的类型,编译器直接支持的数据类型。比如int直接映射到System.Int32类型,就像是添加了using应用:using sbyte=System.SByte.

C#基元类型 FCL类型 说明
sbyte System.SByte 有符号8位
byte System.Byte 无符号8位
short System.Int16 有符号16位
ushort System.UInt16 无符号16位
int System.Int32 有符号32位
uint System.UInt32 无符号32位
long Syetem.Int64 有符号64位
ulong System.Int64 无符号64位
char System.Char 16位Unicode字符
float System.Single 32位浮点值,即带小数
double System.Double 64位浮点值
bool System.Boolean True/False
decimal  [英]'desɪml System.Decimal 128位高精度浮点值
string System.String 字符数组
object System.Object 所有类型的基类
dynamic System.Object

对于CLR,dynamic和Object完全一致

  基元类型只有在数量级别小转大的时候可以隐式转换,数量级别大转小的时候必须显示的转换,如下:

  Int32 i=1;   Int64 l=i;  Single s=i;  -----隐式转换

  Byte b=(Byte)i; Int16 v=(Int16)i;  -----显示转换

  因为数量级别大转小可能会造成内存溢出,需要用到checked喝unchecked,

    使用checked发生溢出时会抛出OverFlowEception异常;

    unchecked允许发生溢出;

2 引用类型和值类型

  1,为什么会有引用类型和值类型

      因为引用类型每一次使用的时候会进行一次内存分配,非常影响程序性能。值类型一般在线程栈上分配,值类型不受垃圾回收器的控制,缓解了托管堆中的压力,减少了一个应用程序在其生存周期内需要进行回收的次数。值类型用 struct来声明。

  2.什么时候用值类型

      1,类型十分简单,成员值不会被修改,建议标记为readonly。

      2,不需要从其他任何类型继承。

      3,也不会派生出其他类型。

      4,类型实例占用小,小于16个字节,大于16个字节时不作为参数传递,也不会被方法返回。

      老赵有一篇经典的struct用法的文章:http://blog.zhaojie.me/2013/04/dont-go-half-way-of-preventing-boxing.html

  3.值类型与引用类型的不同

值类型 引用类型
有2中表示形式:未装箱和已装箱 总是处于已装箱状态

从System.ValueType派生,由于性能问题,定义值类型时候

需要重写Equals和GetHashCode方法

从System.Object派生

不能将值类型作为基类,所以不能写虚方法,不能是抽象方法

,所有方法都隐式地为密封方法

可以继承和派生
所有成员初始化为0(可空除外) 默认值为Null,调用抛出NullReferenceException异常
值类型赋值时会逐字段赋值 引用类型赋值时赋给内存指针
值类型赋值后自成一体,操作不会受影响 引用类型引用的是同一对象,操作会受影响

值类型不在堆上分配,一旦实例方法不处于活动状态,分配的

存储就会被释放,不需要考虑垃圾回收

由GC回收,需要考虑垃圾回收机制。

  4,值类型的拆箱和装箱     

1. 装箱过程?

装箱:将值类型转换为引用类型。当我们把值类型参数传递给需要引用类型参数的方法时,会自动进行装箱操作。过程如下:

        • 从托管堆为要生成的引用类型分配大小。大小为:值类型实例本身的大小+额外空间(方法表指针和SyncBlockIndex)。
        • 将值类型字段拷贝到刚刚分配的内存中。
        • 返回托管堆中新分配内存的地址。也就是指向对象的引用。

2. 拆箱过程?

拆箱:获取指向对象中包含的值类型部分的指针。一般拆箱之后会进行字段拷贝操作,两个操作加起来才是真正与装箱互反的操作。过程如下:

      • 如果引用为Null,则抛出NullReferenceException异常。
      • 如果引用对象不是一个期望值类型的已装箱对象,会抛出InvalidCastException异常。
      • 返回一个指向包含在已装箱对象中值类型部分的指针。

3. 实例

      • 拆箱的转型结果必须是它原来未装箱时的类型。

public static void Main() {

Int32 x = 5;

Object o = x; // 装箱

Int16 y = (Int16) o; // 拆箱,抛出InvalidCastException异常

}

修正:Int16 z=(Int16)(Int32)o;//拆箱成功

    • 这段代码进行了几次装箱?

public static void Main() {

Int32 v = 5; // 创建值变量

Object o = v; // 装箱

v = 123; // Changes the unboxed value to 123

Console.WriteLine(v + ", " + (Int32) o); // Displays "123, 5" ,装箱两次

}

上面的代码进行了3次装箱,最后一行中v被装箱为引用类型,o首先被拆箱然后再装箱为引用类型。

这一段来自小静:http://www.cnblogs.com/janes/archive/2011/07/04/2097540.html

5,dynamic基元类型

      这一段发布的时候自己丢失了,运行时绑定,由dynamic对象的类型来实际决定具体执行的操作!

 using System;

 internal static class DynamicDemo{
public static void Main(){
for(int i=;i<;i++){
dynamic arg=i==?(dynamic):(dynamic)"A";
dynamic result=Plus(arg);
M(result); //这里会自动根据dynamic是什么类型调用相应的方法。
}
} private static dynamic Plus(dynamic arg){
return arg+arg;
}
privaye static void M(Int32 a){
Console.WriteLine("M(Int32)"+a);
} privaye static void M(String a){
Console.WriteLine("M(String)"+a);
}
}

   

 

      

【CLR Via C#】第5章 基元类型、引用类型、值类型的更多相关文章

  1. [Clr via C#读书笔记]Cp5基元类型引用类型值类型

    Cp5基元类型引用类型值类型 基元类型 编译器直接支持的类型,基元类型直接映射到FCL中存在的类型. 作者希望使用FCL类型名称而避免使用关键字.他的理由是为了更加的清晰的知道自己写的类型是哪种.但是 ...

  2. <NET CLR via c# 第4版>笔记 第5章 基元类型、引用类型和值类型

    5.1 编程语言的基元类型 c#不管在什么操作系统上运行,int始终映射到System.Int32; long始终映射到System.Int64 可以通过checked/unchecked操作符/语句 ...

  3. CLR via C#(02)-基元类型、引用类型、值类型

    http://www.cnblogs.com/qq0827/p/3281150.html 一. 基元类型 编译器能够直接支持的数据类型叫做基元类型.例如int, string等.基元类型和.NET框架 ...

  4. C#中的基元类型、值类型和引用类型

    C# 中的基元类型.值类型和引用类型 1. 基元类型(Primitive Type) 编译器直接支持的类型称为基元类型.基元类型可以直接映射到 FCL 中存在的类型.例如,int a = 10 中的 ...

  5. 《CLR via C#》读书笔记--基元类型、引用类型和值类型

    编程语言的基元类型 编译器直接支持的数据类型称为基元类型.基元类型直接映射到Framework类库中存在的类型.例如:C#中的int直接映射到System.Int32类型.下表给出了C#基元类型与对应 ...

  6. CLR:基元类型、引用类型和值类型

    最新更新请访问: http://denghejun.github.io   前言 今天重新看了下关于CLR基元类型的东西,觉得还是有必要将其记录下来,毕竟这是理解CLR成功 之路上的重要一步,希望你也 ...

  7. 《CLR via C#》读书笔记(5)基元类型、引用类型和值类型

    5.1 基元类型 编译器直接支持的数据类型称为基元类型(primitive type). 以下4行到吗生成完全相同的IL int a = 0; //最方便的语法 System.Int32 b = 0; ...

  8. CLR via C#深解笔记三 - 基元类型、引用类型和值类型 | 类型和成员基础 | 常量和字段

    编程语言的基元类型   某些数据类型如此常用,以至于许多编译器允许代码以简化的语法来操纵它们. System.Int32 a = new System.Int32();  // a = 0 a = 1 ...

  9. 重温CLR(四)基元类型、引用类型、值类型

    编程语言的基元类型 编译器直接支持的数据类型称为基元类型(primitive type).基元类型直接映射到framework类型(fcl)中存在的类型. 下表列出fcl类型 从另一个角度,可以认为C ...

随机推荐

  1. Sql Server 保留几位小数的两种做法

    数据库里的 float momey 类型,都会精确到多位小数.但有时候 我们不需要那么精确,例如,只精确到两位有效数字. 1. 使用 Round() 函数,如 Round(@num,2)  参数 2 ...

  2. Hibernate创建hqll时报错

    Hibernate 问题,在执行Query session.createQuery(hql) 报错误 出错截图: 这条语句在java运行环境下,直接连数据库不出错,如果在hiberante,strut ...

  3. Collection 集合类

    ArrayList: 基于动态数组的List 它有两个重要的变量,size为存储的数据的个数.elementData 数组则是arraylist 的基础,因为他的内部就是通过这个数组来存储数据的. p ...

  4. July 5th, Week 28th Tuesday, 2016

    If you smile when no one else is around, you really mean it. 独处的时候你的笑容才是发自内心的笑容. Human beings are so ...

  5. SQL错误级别 状态 怎么定义

    关于SQL Server的错误严重性级别的说明,强烈认真看一下下面的两个链接 脱机帮助 ms-help://MS.SQLCC.v9/MS.SQLSVR.v9.zh-CHS/sqlerrm9/html/ ...

  6. Delphi线程基础知识

    参考http://blog.chinaunix.net/uid-10535208-id-2949323.html 一.概述 Delphi提供了好几种对象以方便进行多线程编程.多线程应用程序有以下几方面 ...

  7. 11g 使用rman duplicate复制数据库,创建辅助实例

    一,创建所需目录 1)创建审计文件目录 PROD1@dbrac1 /dsg/oracle11$ cd $ORACLE_BASE/admin PROD1@dbrac1 /u01/app/oracle/a ...

  8. c++ 左值右值 函数模板

    1.先看一段代码,这就是一种函数模板的用法,但是红色的部分如果把a写成a++或者写成一个常量比如1,都是编译不过的,因为如果是a++的话,实际上首先是取得a的 值0,而0作为一个常量没有地址.写成1也 ...

  9. POJ1351 Number of Locks(数学)

    截至写博客为止,貌似这是网上第一个采用数学公式来处理的. 网上的题解都是DFS或是动态规划,但感觉可以推公式直接用数学的方法处理,想了好久,终于推出公式. 题意:一个长度为n的由数字1,2,3,4 组 ...

  10. 攻城狮在路上(壹) Hibernate(十一)--- 映射实体关联关系

    本文以Customer和Address类的关系为例说明一对一关联映射:以Category和Item类的关系说明多对多关联关系.一.映射一对一关联: 分两种情况:按照外键映射和按照主键映射.这两种方式的 ...