繁体   English   中英

如何调用一个显式接口实现的基础 function?

[英]How to call a base function that's an explicit interface implementation?

基本问题(伪代码):

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();
   }
}

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

我建议稍微更改您的基本 class 以便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[]数组来指定 arguments。

您无法基于接口类型调用base ,但您可以重构您的类以使其成为可能。

通过将方法的内容移动到protected的方法中,您可以由两个类直接调用它,如下所示:


interface ISomethingDoer
{
    void DoSomething();
}

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

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

class B : A, ISomethingDoer
{
    void ISomethingDoer.DoSomething()
    {
        if (reason)
        {
            base._DoSomething();
        }
        SomethingElse.Do();
    }
}

这可能是一个很好的基本实现:

public interface IAnimal
{
    void Eat();
}

public class Animal : IAnimal
{
    public void Eat()
    {
        Console.WriteLine("This Animal is Eating!");
    }
}

public class Shark : Animal
{
    public void Eat(bool useBase)
    {
        if (useBase)
        {
            base.Eat();
        }
        else
        {
            Console.WriteLine("This Shark is devouring everything with 120840128904 teeth");
        }
    }
}

我总是将私有实现作为方法的包装器。

interface ISomethingDoer
{
    void DoSomething();
}

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

class B : A, ISomethingDoer
{
    protected void DoSomethingElse()
    {
        if (reason)
        {
            base.DoSomething();
        }
        SomethingElse.Do();
    }
    void ISomethingDoer.DoSomething() => DoSomethingElse();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM