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

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

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

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. yii验证码不使用model在控制器中进行验证

    控制器 public function actionCheckLogin(){ if(!$this->createAction('verify_code')->validate($_POS ...

  2. objective-c数组

     1 #pragma mark -----------数组的初始化方式--------------  2 //        insert code here...  3 //        NSLo ...

  3. linux初体验

    linux系统和window一样,也是一套独立的操作系统,它只是没有图形化界面而已

  4. file标签选择文件change事件失效处理方法

    file只能处罚一次change事件,在change事件中重新替换file标签即可生效 eg: $(function(){ //上传图片 $("body").on("ch ...

  5. iOS - 日期的时间差(某年某月某日的某一天。。。)

    //首先创建格式化对象 NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setDateF ...

  6. python中random模块使用

  7. linux中解决SSH连接慢问题 关键点GSSAPIAuthentication

    [root@ok 6FE5-D831]# ssh -v xxx.xxx.xxx.64 OpenSSH_5.3p1, OpenSSL Feb debug1: Reading configuration ...

  8. Delphi版本顺序

    1.02.03.04.05.06.07.08.0200520062007 现在应该又出新的版本了

  9. 学习一下《JavaEE开发的颠覆者 Spring Boot实战 》

    SPRING,绕不过去的.

  10. hdu 1247:Hat’s Words(字典树,经典题)

    Hat’s Words Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total ...