How to do proper Reflection of base Interface methods

后端 未结 3 1614
耶瑟儿~
耶瑟儿~ 2020-12-18 21:33

I have 2 interfaces and 2 classes that I investigate via Reflection:

  • IParent
  • IChild - derives from IParent
  • Parent
  • Child - derives f
3条回答
  •  长情又很酷
    2020-12-18 22:31

    The base interfaces of an interface (in this case IParent is the base interface of IChild) are explicit base interfaces. Inheritence is an unfortunate word for interfaces, because classes, structures, and other interfaces never inherit from interfaces, they simply implement the contract that the base interfaces define.

    When you derive IChild from IParent (note I did not say inherit), it does not define the ParentMethod method, it simply says anything that implements me, must also implement IParent.

    The reason it works when you reflect on an actual type, is because implementing an interface actually does define that method signatures in the type itself, and that's not the case with interfaces.

    This is due to a process that occurs by the compiler called interface mapping, which is defined as the process of locating interface members in an implementing class or struct, but this does not occur for the interface itself.

    When you reflect upon an interface, interface mapping does not occur, so only the interface itself is reflected.

    Type t = typeof(IChild);
    

    The type information will only contain type information explicitly about IChild.

    Type t = typeof(Child);
    

    Here the process of interface mapping does occur. When you reflect upon the type of Child for a method named ParentMethod, each base interface is examined until a match is found.

    This part of the language design. You can read more about it in section 13.1.4 of the C# Programming Language (Fourth Edition) or section 20.1.2 of the ECMA spec.

    You can work around it somewhat by doing interface reimplementation, but it requires some extra code.

    interface IParent
    {
        void ParentMethod();
    }
    
    interface IChild
    {
        new void ParentMethod(); // Reimplement IParent.ParentMethod()
        void ChildMethod();
    }
    

    This would work.

    Type t = typeof(IChild);
    MethodInfo mi = t.GetMethod("ParentMethod");
    

    Because of interface reimplementation, IChild now contains a method signature of ParentMethod.

提交回复
热议问题