zoukankan      html  css  js  c++  java
  • 第五章 基元类型

    5.1.基元类型和FCL类型

    编译器直接支持的类型是基元类型,int ,long,string等

    FCL:内置类型 一个基元类型必然映射一个FCL类型,不然你的代码怎么执行。

    int->int32, long->int64
    错误认识: int 在32位机器上是32位整数,64位置机器代表64位整数,这是错误的认识。

    还有还多东西感觉用不上就不用记了,实际生产几乎用不到

     

    5.2引用类型和值类型

       字面上所有属于类的都是引用类型,结构、枚举都是值类型。
    别惊讶你对值类型有误解,你所知道的int类型是精准叫法是:隐射System.Int32结构。他们是值类型的一种而不是值类型的全部。

      另外值类型都是隐式密封。无法作为基类出现。想想为啥呢?

      参考下这个设想:

    Animal animal=new Dog(); //正常 Dog 的基类式 Animal    

     Int32 temp_int32= “5”; //正常吗?Int32的基类假如是string 岂不是乱套了

    另外:是可以控制我们类型中的字段布局,通过StructLayoutAttribute特性,就不做更深入的解释了

     说点有用的:

    内存分配:

       值类型分配在线程栈上,应用类型分配在堆上。对CRL初始化不清楚的同学参考下前面几篇文章。

    值类型仅在栈上是给值类型的具体值,

    引用类型则实际内存分配在堆上,并且堆上保留着一个该对象的 对象类型指针、同步索引块、字段、方法、等。栈上的变量仅仅是个地址指向堆上的对象类型指针。

     

    拆箱、装箱:想办法将两种不同类型的对象在内存上的分配方式转化过来即可。

     

    装箱:拷贝栈数据到堆上,并且初始化了 套餐(见本系列第一篇末尾什么套餐定义)返回套餐种的对象类型指针地址。形成装箱。

    Int age=2;     Object age2=age;

     

    拆箱:拷贝内存堆上的未装箱部分即引用对象的实际值到栈上。然后返回

     Object age2=age;  int age=(int)age2;

     

     

    .3.2对象相等性和同一性 简单介绍:

    相等一般指值类型,同一性指引用类型对象指针指向相同。

    System.Object提供了名为Equals的虚方法,作用实在两个对象包含相同值的前提下返回true。因此所有对象都可以重写该方法。

    同一性判定:ReferenceEquals 指出了是否指向了同一个对象。

    其他的讲了一堆实用性门槛高,不做赘述。

     

    额外扩展:ToString()差点漏了个知识点。补上,这个ToString()是一个object的虚方法,凡是调用了基类的虚方法的ToString()就会发生装箱,判定标准是有没有用到 object.ToString();有就装箱。感谢同事 林音小(艺名)的指出

     

    5.4对象哈希码

     对象哈希码相同才能认为是同一个对象,那么重写了Equals方法的对像需要重写对象的hash码,比如 字典类型的对像、Hash table.这句话理解就是不重写 hash code 影响的是依据 hash code 判定是否相等的对象。

    5.5动态类型

    Dynamic  表示对象类型将在运行时解析,平时见到的都是在编译时候解析。

    Dynamic会在最后被解析认为是object类型

    其他的知识不做深入介绍,

    理解和var 的区别 :var 要求编译器能准确推断类型,属于变量命名的一种简写。

    最后别人归纳的笔记好的直接拷贝过来用:

    1.dynamic基元类型是为了方便开发人员使用反射或者与其它非.net组件通信.

    2.代码使用dynamic表达式/变量时,编译器生成特殊的IL代码来描述这种操作。这种特殊的代码被称为payload(有效载荷)。

    3.在运行时,payload根据dynamic表达式/变量引用的对象的实际类型来决定具体执行的操作。

    4.dynamic类型在编译后实际上是作为System.object,然而它在元数据中被应用了System.Runtime.CompilerServices.DynamicAttribute的实例。局部变量除外,因为Attribute显然不能在方法内部使用。

    5.另外使用的泛型的dynamic的代码时,泛型代码已经变异好了,将类型视为Object,编译器不在泛型代码中生成payload,所以也不会执行动态调度。

    6.且编译器允许使用隐式转型语法,将表达式从dynamic转型为其它类型。

    dynamic a=123;

    Int32 b=a;

    7.另外dynamic表达式的求值结果也是一个dynamic类型。

    不能定义对dynamic进行扩展的扩展方法,不能将lambda表达式或匿名方法作为实参传给dynamic使用。

    8.为COM对象生成可由“运行时”调用的包装时。Com组件的方法中使用任何Variant实际都转化为dynamic,这称为动态化。显著简化了与COM对象的操作。

    9.当然用dynamic会有额外的性能开销,因为会引用一些必须的dll,然后执行一些动态绑定啊什么的。如果只是一两处用这个东西,还是用传统方法好一点。(一般会引用Microsoft.CSharp.dll,与com组件操作还会用到System.Dynamic.dll)

     

    这里这位网友没有解释清楚为啥dynamic,会影响性能,使用它时候

    会引用Microsoft.CSharp.dll 这个DLL会间接引用 System.DLL和System.Core.DL而这两个DLL又会间接引用别的DLL。引用就算了,那么为啥会造成性能消耗呢,因为运行是绑定是发生在三大域一个堆中的AppDomian中,这个是我们程序运行的地盘,因此多了会影响程序正常运行,得不偿失。关于什么是三大域一个堆后续再说吧。

  • 相关阅读:
    新一代MQ apache pulsar的架构与核心概念
    Flutter使用fluwx实现微信分享
    BZOJ3622 已经没有什么好害怕的了 动态规划 容斥原理 组合数学
    NOIP2016提高组Day1T2 天天爱跑步 树链剖分 LCA 倍增 差分
    Codeforces 555C Case of Chocolate 其他
    NOIP2017提高组Day2T3 列队 洛谷P3960 线段树
    NOIP2017提高组Day2T2 宝藏 洛谷P3959 状压dp
    NOIP2017提高组Day1T3 逛公园 洛谷P3953 Tarjan 强连通缩点 SPFA 动态规划 最短路 拓扑序
    Codeforces 873F Forbidden Indices 字符串 SAM/(SA+单调栈)
    Codeforces 873E Awards For Contestants ST表
  • 原文地址:https://www.cnblogs.com/LiMin/p/10792942.html
Copyright © 2011-2022 走看看