How to call an explicitly implemented interface-method on the base class

后端 未结 7 1202
死守一世寂寞
死守一世寂寞 2020-12-05 09:56

I have a situation, where two classes (one deriving from the other) both implement the same interface explicitly:

interface I
{
  int M();
}

class A : I
{
          


        
7条回答
  •  忘掉有多难
    2020-12-05 10:25

    It is possible using reflection.
    The code follows. I added caching as a basic optimization, but it can be optimized further by using Delegate.CreateDelegate on methodInfo. Also, parameter count and type checks can be added using methodInfo.GetParameters().

    interface I   
    {   
        int M();   
    } 
    
    class A : I   
    {   
        int I.M() { return 1; }   
    } 
    
    class B : A, I   
    {   
        BaseClassExplicitInterfaceInvoker invoker = new BaseClassExplicitInterfaceInvoker();
        int I.M() { return invoker.Invoke(this, "M") + 2; }   
    }
    
    public class BaseClassExplicitInterfaceInvoker
    {
        private Dictionary cache = new Dictionary();
        private Type baseType = typeof(T).BaseType;
    
        private MethodInfo FindMethod(string methodName)
        {
            MethodInfo method = null;
            if (!cache.TryGetValue(methodName, out method))
            {
                var methods = baseType.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly);
    
                foreach (var methodInfo in methods)
                {
                    if (methodInfo.IsFinal && methodInfo.IsPrivate) //explicit interface implementation
                    {
                        if (methodInfo.Name == methodName || methodInfo.Name.EndsWith("." + methodName))
                        {
                            method = methodInfo;
                            break;
                        }
                    }
                }   
    
                cache.Add(methodName, method);
            }
    
            return method;
        }
    
        public RT Invoke(T obj, string methodName)
        {            
            MethodInfo method = FindMethod(methodName);
            return (RT)method.Invoke(obj, null);
        }
    
    }   //public static class BaseClassExplicitInterfaceInvoker
    

    Here is the source of my inspiration.

提交回复
热议问题