zoukankan      html  css  js  c++  java
  • clr via c#读书笔记四:call、callvirt

    1、嵌套类,就是定义在类中的类;嵌套类可以访问外部类的方法、属性、字段而不管访问修饰符的限制,但是外部类只能够访问修饰符为public、internal的嵌套类的字段、方法、属性;

    2、CLR如何调用虚方法、属性和事件:

    IL提供两个方法调用指令:call和callvirt。

    call调用静态方法、实例方法和虚方法;callvirt调用实例方法和虚方法,不能调用静态方法;

    call关心的是编译时类型;callvirt关心的是运行时类型;所以,用callvirt调用虚方法时,CLR要调查发生调用的对象的实际类型,为了确定类型,发生调用的变量绝不能是null。

    如有两个类:

    internal class Person{
        
    }
    internal class Employee:Person{
    
    }
    void main(){
       Person p=new Employee();//p在编译时的类型是Person,而在运行时的类型是Employee
    }
    

    call不会检测对象是否为null。而callvirt会检测。所以callvirt指令的执行速度比call指令稍慢。

    3、C#用callvirt指令调用所有实例方法。

    但是编辑器有时用call而不是callvirt调用虚方法。虽然刚开始有点难以理解,但是以下证明了有时需要这样做:

    internal class SomeClass{
        //ToString是基类Object定义的虚方法
        public override String ToString(){
            //编译器使用IL指令'call'
            //以非虚方式调用Object的ToString方法
            //如果编辑器用'callvirt'而不是'call',
            //那么该方法将递归调用自身,直至栈溢出(但是为什么会递归调用自身呢,这里不是base吗,是基类吗?)
            return base.ToString();
        //我的理解:这里实际和reutrn this.ToString()没区别,因为base虽然是基类指针,但是用callvirt时,会检测实际类型,而实际类型就是自身,所有会无限递归调用自身的方法。(不知识这样理解对不对)
      }
    }
    

      

  • 相关阅读:
    Confluence未授权模板注入/代码执行(CVE-2019-3396)
    Python实现批量处理扫描特定目录
    windows10 缺失 msvcp140.dll 解决办法
    nessus 故障处理
    python 处理json数据
    python 实现两个文本文件内容去重
    python3 实现多域名批量访问特定目录(一)
    python 简单的实现文件内容去重
    python 实现爬取网站下所有URL
    php强大的filter过滤用户输入
  • 原文地址:https://www.cnblogs.com/yuzhoumanwu/p/8537464.html
Copyright © 2011-2022 走看看