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中,这个是我们程序运行的地盘,因此多了会影响程序正常运行,得不偿失。关于什么是三大域一个堆后续再说吧。