Согласованность наследования интерфейса - PullRequest
3 голосов
/ 09 марта 2012

Первый взгляд на этот код:

class Program
{
  static void Main(string[] args)
  {
    var x =(Base) new Derived();
    ((IMethod)x).DoWork();

    Console.ReadKey();
  }
}

interface IMethod
{
  void DoWork();
}

abstract class Base : IMethod
{
  void IMethod.DoWork()
  {
    Console.WriteLine("Base.DoWork");
  }
}

class Derived : Base, IMethod
{
  public void DoWork()
  {
    //here I where I want to call base.DoWork();
    Console.WriteLine("Derived.DoWork"); 
  }
}

Выход:

Derived.DoWork

Желаемая:

Base.DoWork
Derived.DoWork

Я имею дело с API, который предоставляет интерфейс, который при реализации будет вызывать метод DoWork в некоторой части процессии.

Теперь в приведенном выше примере класс Base является частью API, который внутренне (в API) уже явно реализует этот интерфейс и выполняет некоторые важные исполнения в методе DoWork.

Мне также нужно переопределить реализацию IMethod в моем производном классе, поэтому я получаю уведомление при необходимости, проблема в том, что я не могу «переопределить» метод и вызвать базовый метод, также я не могу привести база до IMethod.

Есть решение?

Примечание : отражение не будет работать, так как это проект Silveright, и вызов частного метода запрещен.

Ответы [ 3 ]

3 голосов
/ 09 марта 2012

Вы можете просто составлять классы вместо использования наследования? Затем вы можете реализовать DoWork() так, как вам нравится, и при этом вызывать DoWork() для объекта Base. Поскольку Base является абстрактным, вам нужно получить фиктивный тип, чтобы все заработало.

class Derived : IMethod
{
    private class SneakyBase : Base
    {
        // abstract implementations here
    }

    private IMethod baseObject = new SneakyBase();

    void DoWork()
    {
        baseObject.DoWork();

        // Custom DoWork code here
    }
}

Очевидно, что делать это таким образом немного больно, но разработчики API сделали странный выбор с явной реализацией интерфейса, и теперь вы платите за это.

1 голос
/ 21 марта 2012

Я нашел комментарий DanBryant , чтобы быть ответом, хотя, как он упоминает, немного рискованно, так как мы не можем гарантировать, что разработчик вызовет базовый метод, но это приличный способ.

Я создал защищенный виртуальный метод, который вызывается из реализации частного интерфейса, затем в производном классе вместо того, чтобы беспокоиться об интерфейсе, я просто хочу переопределить базовый класс и вызвать из него базовую реализацию, которая работает идеально, пример:

abstract class Base : IMethod
{
  void IMethod.DoWork()
  {
    DoWork();
  }

  protected virtual void DoWork()
  {
    Console.WriteLine("Base.DoWork");
  }
}

class Derived : Base
{
  protected override void DoWork()
  {
    base.DoWork();
    //here I where I want to call base.DoWork();
    Console.WriteLine("Derived.DoWork");
  }
}
1 голос
/ 09 марта 2012

Вы ищете:

public class Derived : Base
{
    public override void DoWork()
    {
        base.DoWork();
    }
}
...