重载运算符的函数是Static,使用operator关键字
我想应该是因为避免使用实例调用
Main()函数为什么是静态的,其形参一定是str[]型
Main()是程序的入口,若不是静态,在mainI()不存在对象对他进行调用。
MSIL指令的一些解析
Entrypoint 程序入口
Newobj 在托管堆上新建对象(引用)
Ldstr
C#类型CLR内存模型
线程堆栈(thread stack):每个线程堆栈有1M大小,存储值类型数据,由其分配。而值类型不存在内存泄漏问题
托管堆(Managed Heap):分配引用类型数据,因为需要CLR自动回收内存。
计算堆栈(Evaluation Stack):由线程堆栈分配,每个方法有一个
String特殊的引用类型
String不使用newobj而使用ldstr指令,编译时,将字串作为常数写入程序集元数据,.net中使用“字串拘留池(intern pool)”,对池中已有的字串不重复创建对象,而只返回引用。
CLR对象管理机制
内置类型(值类型):CLR为每个类型有一张类型表,如图所示(示意图,实际情况可能不一样)
用户自定义类型:大体与上述内置类型一样有类型表,不同的是,用户自定义类型的相关信息放在程序集的元数据中。
引用类型:如图所示,要注意实例字段与静态字段是分开存放的,方法表放在类型表中。
CLR对方法的JIT编译
1. 程序第一次运行时,CLR从元数据中取MyClassExample类型信息,并创建类型表,每个方法对应一个Method Stub,内容为调用CLR的JIT call指令。
2. 当F()第一次调用时,CLR查找并取出MethodStub,其为JIT的call指令,CLR取相应的IL指令送给JIT编译器,编译成在本地可执行的本地代码。
3. CLR将这代码缓存起来,并将这MethodStub替换为无条件跳转的JMP指令。(下次运行则不用再次编译该方法)
如图所示
值类型与引用类型变量初始化
Reference:分配对象内存时就指定其为引用型
ValueType:为值变量分配内存,将该变量地址装入计算堆栈,最后用initobj完成初始化。
索引器(this)
类的索引器有点像数组,可以进行检索,可读写,可重载