接口继承一致性

3

首先看一下这段代码:

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项目,因此反射将不起作用,而且私有方法调用被禁止。


为什么要混合两种风格的接口实现? - dkackman
2
你的基类显然没有考虑到这种继承方式;通常,如果基类希望允许行为被覆盖,它会提供一个受保护的虚拟方法来实现显式实现的逻辑。鉴于此,即使你能找到一种方法来“强制”这种覆盖行为,也存在风险,因为你实际上是以原始开发人员未设计的方式派生自该类。尽管如此,这仍然是一个有趣的问题。 - Dan Bryant
@DanBryant,我们先把设计放一边(除此之外别无选择),但是不要忘记我需要像基类一样实现接口,并且两个方法都必须被调用。请看我的更新答案。 - Shimmy Weitzhandler
@DanBryant,实际上你的解决方案就是我要做的,我将在基类中调用一个受保护的虚方法,并在派生类中重写它。请发布为答案。 - Shimmy Weitzhandler
3个回答

3

你能否仅编写类而不使用继承?这样,您可以随意实现DoWork(),同时仍然在Base对象上调用DoWork()。由于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设计师在明确接口实现方面作出了奇怪的选择,现在你正在为此付出代价。

不行,基类是抽象的!此外,在我的情况下,我确实必须重写它。 - Shimmy Weitzhandler

1

我发现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

您正在寻找:

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

3
不行,Base类实际上没有名为DoWork()的方法。 - dlev
啊,你说得对。我没有注意到它使用了接口实现。@Shimmy,更改方法的定义以不显式实现接口(例如,public virtual void DoWork())是否可行? - pickypg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接