C#-CLR-5

IL代码检测Main的代码引用的所有类型,分配一个内部结构来管理都引用类型的访问

jitcompiler:
1 在元数据中查找被调用的方法
2 从元数据中获取该方法的IL
3 分配内存块
4 将IL编译成本机cpu指令,存到3分配的地址
5在type表修改与方法对应的条目,使它指向步骤3的内存块
6 跳转到内存块中的本机代码

第二次调用的时候是不需再调用jitcompiler函数的

5.1 int类型不管是在64位还是32位机器, 对C#来说都是对应Int32.

5.1值类型:所有值类型都成为结构或者枚举

所以这个所谓的“提领”其实就是“获取指针地址或引用地址上的值”的意思,按照构词法可直译为“引用解析”

声明为值类型的条件:
1,类型具有基元类型的行为。
2,类型不需要继承自其它类型。
3,类型也不需要派生出其它类型。
还有满足一下之一:
1,类型的实例较小(16字节或者更小--很难吧??)
2,类型的实例较大,但不作为方法实参传递,也不从方法返回。--有感

区别:
1未装箱、已装箱 ;已
2,值类型兄ValueType派生
3,不能继承派生,struct的方法都隐式密封
4,初始值; null
5,逐字段复制;内存地址复制
6,自成一体;多个引用一个对象操作会互相影响
7,过了生命周期立即释放内存不等垃圾回收;等垃圾回收

值类型调用虚方法,要装箱

5.2 引用类型总是从托管堆里分配:

  • 分配引用类型对象
    1.内存从托管堆分配
    2.堆上分配的每个对象都有一些额外的成员(还需要是初始化了的)
    3.对象中的其他字节设为零
    4.托管堆分配对象可能会触发GC的条件(比如内存不够)

  • 所有的值类型都隐式继承了ValueType, 如果引用类型隐式继承了Object一样, 所以,不能要继承其他类了
    扩展:值、引用类型并不能继承ValueType(即使他是abstract class) net做了特殊处理

  • 内存分配情况:

hashCode的通用规定:
在应用程序的执行期间,只要对象的equals方法的比较操作所用到的信息没有被修改,那么对同一个对象的多次调用,hashCode方法都必须始终返回同一个值。在一个应用程序与另一个应用程序的执行过程中,执行hashCode方法所返回的值可以不一致。
如果两个对象根据equals(Object)方法比较是相等的,那么调用这两个对象中的hashCode方法都必须产生同样的整数结果
如果两个对象根据equals(Object)方法比较是不相等的,那么调用这两个对象中的hashCode方法,则不一定要求hashCode方法必须产生不用的结果。但是程序员应该知道,给不相等的对象产生截然不同的整数结果,有可能提高散列表的性能。
由上面三条规定可知,如果重写了equals方法而没有重写hashCode方法的话,就违反了第二条规定。相等的对象必须拥有相等的hash code。

5.3不能用接口更改已装箱的值类型中的字段

 Point p = new Point(1, 1);
 Console.WriteLine(p);
 p.Change(2, 2);
 Console.WriteLine(p);
 Object o = p;
 Console.WriteLine(o);
 ((Point)o).Change(3, 3);
 //输出 2,2 --不是预期的样子,所以不能用接口更改已装箱的值类型中的字段 !!!
 Console.WriteLine("-3-" + o); 

5.5 dynamic基元类型

如果字段、方法参数、方法返回值是dynamic,编译器会转换其为object(如果是值类型,就会装箱)。
编译时可隐性转换,且不会编译错误,但是如果类型不可转换时将会在运行时报错。

dynamic有额外消耗慎用

原文地址:https://www.cnblogs.com/Jaysonhome/p/13293074.html