How to do proper Reflection of base Interface methods

后端 未结 3 1572
耶瑟儿~
耶瑟儿~ 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:25

    Although, we use the interfaces as the same way we use inheritance (":"); interfaces are not inherited; they are to be implemented. In such a case; inheritance is confused with implementation since they are defined using the same operator (":").

    As a summary; IA : IB and A:IA means; any class implementing IA, shall implement IB. In this case; A shall implement IA and IB.

    A:B means A class inherits B class; it does not implement.

    The confusion here derives from using the same operator (":").

    Check this page interface inheritance

    0 讨论(0)
  • 2020-12-18 22:26

    If you are dealing with an interface, use

    t.GetInterfaces()
    

    then you can check for methods on the types returned above.

    Finding interface members by name is not relyable, be mindful that whilst in C# interface members cannot be renamed on implementation, in the CLR the names may be modified. (IDisposable.Dispose() is sometimes renamed to Close). In il there is an instruction called .implements that allows one to change names. I believe VB.Net also has this feature.

    0 讨论(0)
  • 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.

    0 讨论(0)
提交回复
热议问题