首页 > 解决方案 > 如何调用作为显式接口实现的基本函数?

问题描述

基本问题(伪代码):

interface ISomethingDoer
{
   void DoSomething();
}

class A: ISomethingDoer
{
   void ISomethingDoer.DoSomething()
   {
      Something.Do();
   }
}

class B: A, ISomethingDoer
{
   void ISomethingDoer.DoSomething()
   {
      if (reason)
      {
         base.DoSomething(); //this does not compile
      }
      SomethingElse.Do();
   }
}

有没有办法在不从类中删除显式实现的情况下完成这项工作A

标签: c#explicit-interface

解决方案


我建议稍微更改您的基类,以便DoSomething调用受保护的方法:

class A: ISomethingDoer
{
   void ISomethingDoer.DoSomething()
   {
       DoSomethingImpl();
   }

   protected void DoSomethingImpl()
   {
       Something.Do();
   }
}

然后B你可以打电话DoSomethingImpl

class B: A, ISomethingDoer
{
   void ISomethingDoer.DoSomething()
   {
      if (reason)
      {
         DoSomethingImpl(); //this does compile
      }
      SomethingElse.Do();
   }
}

Lasse V. Karlsen建议的替代方法是使用反射:

class B: A, ISomethingDoer
{
   void ISomethingDoer.DoSomething()
   {
      if (reason)
      {
         string baseName = $"{typeof(ISomethingDoer).FullName}.{nameof(DoSomething)}";
         MethodInfo baseMethod = this.GetType().BaseType
             .GetMethods(BindingFlags.NonPublic | BindingFlags.Instance)
             .FirstOrDefault(m => m.IsPrivate && m.IsFinal && m.Name == baseName);
          baseMethod.Invoke(this, new object[0]);
      }
      SomethingElse.Do();
   }
}

但我不喜欢这种方法,因为它使用反射并且会变慢。我用这个答案来帮助我构建反射解决方案。

如果需要过滤方法的不同重载,可以使用GetParameters(),并且可以通过构建object[]包含相同位置顺序的数组来指定参数。


推荐阅读