zoukankan      html  css  js  c++  java
  • 接口一个被我忽略的地方接口重定向技术

    习惯于用IDE生成接口方法了,右键点击"Implement Interface",生成所有的接口方法声明,还带个Region多方便啊.
    今天看<<CLR Vir C#>>时才了解到自己是知其然不知其所有然啊.

     实现接口方法很简单,新手估计也都会,但怎么理解这个过程,不见得所有人都知道

    Base class

    首先我们可以简单的认为Base类里有个Dispose()的方法.这个方法跟是不是IDisposable的成员,先理解为没有关系.当编译这个类的时候,编译器发现它实现了IDisposable接口,于是查找有没有跟其成员IDisposable.Dispose()同名,参数和返回类型完全匹配,并且是public的,如果找到就在IVMap里指向这个方法的入口(我猜的,这地方具体见http://www.microsoft.com/china/MSDN/library/netFramework/netframework/JITCompiler.mspx?mfr=true)如果没有就出个编译错误.

    如果找到的方法前面有virtual关键字,编译器仍然认为是匹配的.如何没有virtual关键字,编译器默认的还会为其加上sealed.那么其子类是无法override的.如何想要override父类的Dispose()方法,最好是在Base中定义Dispose()时使用virtual.当然如果我们没有权利改写Base类,我们可以让其子类同样继承自IDisposable,然后改写方法.这点已经有很多人谈论过了,估计大家基本都明白.不了解的可以gongle it!
    Derived

    现在问题来了,我们是真的改写了父类的Dispose()方法吗?
    测试一下:
    Base c = new Derived();
    c.Dispose();
    结果你可以发现输出的是: Base's Dispose.当时我觉得很奇怪,后来静下来想想原来可以这么理解.
    就如我开始理解接口实现过程一样,对于上面的代码我们可以直接忽略接口的存在,等效如下

    Remove Interface

    这样大家应该都知道为什么输出是Base's Dispose,如果不知道可以去查看 "今天你多态了吗"一文,说的很详细了.
    回过来看我们刚才的代码,编译的时候有个警告:   'Program.Derived.Dispose()' hides inherited member 'Program.Base.Dispose()'. Use the new keyword if hiding was intended. 
    是不是把Dispose()看成只是类的方法更容易理解呢.只是通过接口调用的时候指向了这个方法的入口而已.

    我以为如下实现Derived类会更好些,不会让你产生误解,以为Derived  override了Base类的Dispose()方法

    显示实现接口

    对于如下代码不要期待能输出Derived's Dispose结果.当然如果CallDispose()传入的参数类型是IDisposable,就当我没说过
    static void Main(string[] args)
    {
        Derived c = new Derived();
        CallDispose(c);
    }
    private static void CallDispose(Base b)
    {
        b.Dispose();
    }

    要不然你得这样
    private static void CallDispose(Base b)
    {
        ((IDispose))b.Dispose();
    }
    但是你会觉得很别扭.当然 CallDispose(Base b)定义成这样本身就是个不好的设计.

    具体大家可以看看<<CLR Vir C#>>14章,我想对于你理解接口实现的整个过程会有莫大的帮助

  • 相关阅读:
    模型层
    视图层,模板层
    ORM表关系建立
    CMakeList入门
    C++标准模板库
    C++基本语法
    g++应用说明
    Linux快捷键
    Git 操作备忘
    Block的详细介绍
  • 原文地址:https://www.cnblogs.com/anders06/p/780719.html
Copyright © 2011-2022 走看看