当前位置: 首页 > news >正文

西安知名网站建设公司线上网络平台推广

西安知名网站建设公司,线上网络平台推广,网络设计基本原则,wordpress 網頁設計颠覆你对方法调用的看法!http://www.cnblogs.com/francisYoung/p/3371106.html注意:如果你是一个初学者,对实例方法,虚方法的调用还不太清楚,强烈建议你不要阅读本文,因为这里面的代码会让你完全崩溃掉。如…
颠覆你对方法调用的看法!
http://www.cnblogs.com/francisYoung/p/3371106.html
注意:如果你是一个初学者,对实例方法,虚方法的调用还不太清楚,强烈建议你不要阅读本文,因为这里面的代码会让你完全崩溃掉。

如果你对实例方法,虚方法的运行机制已经了如指掌,并且,对方法和对象的内存布局也心中有数,那么本文可能会颠覆你以前对他们的认识。

阅读本文的最佳方式就是亲自演练一下,如果看完之后有疑惑,那么是正常的,但是稍加思考就会想明白。



我说,string变量可以直接引用一个object对象!

我说,派生类型的变量可以直接引用基类型的对象!

你会说,老兄,别开玩笑了,派生类型怎么可以指向一个基类型的对象呢!



我会让你见证一下奇迹,并在文章的结尾再给你一个更加不可思议的例子。



首先,请看下面的代码:
第二个例子:

下面的这个例子也很不可思议,同样会颠覆你传统的观点。

让我们将上面的print方法改为virtual方法,最终如下:
[StructLayout(LayoutKind.Explicit)]class Manager {[FieldOffset(0)]public  Base b = new Base();[FieldOffset(0)]public Derived derived;}class Base {public virtual void Print() {Console.Write("in base");}}class Derived : Base {public override void Print() {Console.WriteLine("in derived");}}

现在,运行如下测试代码:

 

class Program {static void Main(string[] args) {Manager m = new Manager();m.derived.Print();Console.Read();}}

 

这次结果会是什么呢?强烈建议你自己思考答案。

结果是,In Base!

是不是及其不可思议!为了更清楚的理解原因,请看下图:
class Program {static void Main(string[] args) {Derived d=(Derived)new Base();d.Print();Console.Read();}}class Base {public void Print() {Console.Write("in base");}}class Derived : Base {public new void Print() {Console.WriteLine("in derived");}}

毫无疑问,在运行时一定会抛出一个异常,因为Base对象无法转换为Derived对象。



但是,现在,我就想让d指向Base对象,并且可以调用Base中的Print方法,该怎么做呢?



用FiledOffset可以做到这一点,但首先需要定义一个叫做Manager的类,里面包含两个实例字段,一个为Derived,一个为Base。如下:

 

[StructLayout(LayoutKind.Explicit)]

 

    class Manager {

 

        [FieldOffset(0)]

 

        public  Base b = new Base();

 

 

        [FieldOffset(0)]

 

        public Derived derived;

 

    }
这里,尽管derived指向的是Base对象,但是,当CLR看到derived.Print这行代码时,由于Print是虚方法,所以CLR会查看derived所指向的Base对象。

CLR发现Base对象里的type object pointer指向一个Base type object,于是就调用Base Type object中的Print方法,所以最终会输出InBase。



总结:

没有总结可不好。

本质上,子类型是不能引用父类型对象的。但是,我们可以通过FieldOffset绕过这一限制。通过子类型的变量来调用父对象的方法,这很是不可思议,但更不思议的是,当子类型的变量指向父对象时,竟然可以调用子方法!

那么上面的本质是什么呢?当CLR调用一个非虚方法时,不会关心变量具体指向的是什么,因为CLR此时是通过变量的类型来调用方法。如果方法时虚方法,那么CLR为了实现多态,需要查看这个变量指向的是什么对象,然后在通过对象的type object pointer找到对应的Type Object,然后调用Type Object中的方法。
现在,通过为b和derived都指定了相同的偏移,所以,b和derived都指向了同一个对象,Base对象。

由于derived现在指向了Base对象,那么如果我调用d.Print方法,调用的是Base的Printf还是Derived的Print方法,还是抛出一个异常。请看如下代码:
1
2
3
4
5
6
7
class Program {
        static void Main(string[] args) {
            Manager m = new Manager();
            m.derived.Print();
            Console.Read();
        }
    }

运行上面代码,会输出什么呢?

答案是,“In Derived”。



这很不可思议,因为derived指向的是Base对象,现在调用的确实Derived的方法。想要了解原因,请看下图:
这里,尽管derived指向的是一个Base对象,但是,CLR发现Print是一个非虚方法,所以CLR并不关心derived变量指向什么对象,CLR根据derived变量的类型来调用Print方法,这里derived是一个Derived类型,所以CLR会调用Derived中的Print,最终输出In Derived。

 

 

转载于:https://www.cnblogs.com/hongjiumu/p/3377627.html

http://www.lbrq.cn/news/2394019.html

相关文章:

  • 青岛网站建设 上流刚刚发生了一件大事
  • 青岛私人做网站网上企业推广
  • 保定网站建设优化西安seo霸屏
  • ppt做会动彩字网站手机网站建设案例
  • 网站推广文案怎么写医院网络销售要做什么
  • 有什么做照片书的网站百度seo排名优化软件
  • 西藏自治区住房建设厅网站软件定制
  • 旅游网络推广怎么做seo手机优化软件哪个好用
  • wap网站制作市场营销推广策略
  • 腾虎广州网站建设湖南省人民政府
  • 网站制作维护线下宣传渠道和宣传方式
  • wordpress 分类目录 路径广东网络seo推广公司
  • 太原seo建站微信推广平台收费标准
  • 模板和网站可以分开吗公众号推广
  • 企业网站资料大全企业微信scrm
  • 中国建设局网站招聘计算机培训班培训费用
  • 广州南沙建设和交通局网站网络营销的一般流程
  • 温州网站建站模板个人如何做百度推广
  • 微信电商小程序信息流广告优化师
  • 政府部门网站建设方案seo网络营销技巧
  • 用sql2000做网站泉州关键词优化软件
  • 创建网站怎么赚钱的分销渠道
  • 山西科技网站建设济南网站优化公司哪家好
  • 深圳市做网站的有那些公司注册网站查询
  • 北京棋森建设有限公司网站怎么做公众号
  • 陕西党建网站两学一做常态化山东最新消息今天
  • 建设视频网站要求吗全网推广平台有哪些
  • 兰州建网站seo研究中心vip教程
  • 自己做网站挣钱吗宁德市医院
  • 微信导航网站模板seo深圳优化
  • 论文略读: RASA: RANK-SHARING LOW-RANK ADAPTATION
  • 板子 5.29--7.19
  • Git 完全手册:从入门到团队协作实战(2)
  • 配置华为交换机接口链路聚合-支持服务器多网卡Bind
  • 工业数据集成中间件工具OPC Router详细介绍
  • vue中的this.$set