Interface inheritance consistency

蹲街弑〆低调 提交于 2019-12-14 01:36:43

问题


First look at this code:

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

Output:

Derived.DoWork

Desired:

Base.DoWork
Derived.DoWork

I'm dealing with an API that exposes an interface that when implemented, the DoWork method will be called at some part of the procession.

Now in the above example, the class Base is a part of the API, that internally (in the API) already explicitly implements that interface and does some important executions in the DoWork method.

I need to override the implementation of the IMethod in my derived class as well, so I get notified when needed, the problem is I can't 'override' the method and call the base method, neither can I cast base to IMethod.

Any solution?

Note: reflection won't work since it's a Silveright project, and private method invoking is prohibited.


回答1:


Are you able to just compose the classes, rather than using inheritance? Then you can implement DoWork() however you like, and still call DoWork() on the Base object as well. Since Base is abstract, you'll need to derive a dummy type to get everything to work.

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

    private IMethod baseObject = new SneakyBase();

    void DoWork()
    {
        baseObject.DoWork();

        // Custom DoWork code here
    }
}

It's obviously a bit of pain to do things this way, but the API designers made an odd choice with the explicit interface implementation, and you're now paying for it.




回答2:


Are you looking for:

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



回答3:


I've found DanBryant's comment to be the answer, although as he mentions is a bit risky since we can't assure the implementer will call the base method, but is a decent way tho.

I made a protected virtual method that is called from the private interface implementer, then, in the derived class, instead of worrying about the interface, I just care about overriding the base class and calling the base implementation from it, that works perfect, example:

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


来源:https://stackoverflow.com/questions/9627611/interface-inheritance-consistency

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!