【问题标题】:Interface implementation with different method names不同方法名的接口实现
【发布时间】:2015-11-21 19:11:54
【问题描述】:

我有这个界面:

public interface INameScope
{
    void Register(string name, object scopedElement);
    object Find(string name);
    void Unregister(string name);
}

但我希望我的实现有不同的方法名称。我的实现已经有一个具有另一种含义的 Register 方法。

是否有一种方法可以使实现的方法具有“RegisterName”、“FindName”或“UnregisterName”之类的名称,而不必使用完全相同的名称?

【问题讨论】:

  • 为什么不改界面?
  • 我的错。不清楚您是否无法从问题中调整界面。
  • 我今天在 C# 中遇到了这个问题。让我抓狂的是,它在 Visual Basic 中可用(我在以前的工作中使用过):Public Function MyCustomRegisterMethod() Implements INameScope.Register。接受的答案对我来说还不够好,因为功能取决于我是将其视为接口还是具体类型。类似于阴影:stackoverflow.com/questions/392721/…

标签: c# .net oop


【解决方案1】:

不完全是,但你可以使用explicit interface implementation

public class SomeScope : INameScope
{
    void INameScope.Register(string name, object scopedElement)
    {
        RegisterName(name, scopedElement);
    }

    public void Register(...)
    {
        // Does something different
    }

    public void RegisterName(...)
    {
        // ...
    }

    ...
}

如果您现有的 Register 方法具有类似的参数,我会非常谨慎地这样做 - 虽然 编译器 会对此感到满意,但您应该问问自己它有多清晰任何阅读您的代码的人:

SomeScope x = new SomeScope(...);
INameScope y = x;
x.Register(...); // Does one thing
y.Register(...); // Does something entirely different

【讨论】:

  • 是的,我知道你的意思。也许应该有一个带有名称范围(关联)的托管类并公开其方法,例如 public RegisterName(...) { namescope.Register(...) }。那么,这更像是一个设计问题?
  • @SuperJMN:是的,这很有意义 - 除了你不能使用你现有的类来期待INameScope
  • 很好,乔恩。但这对我来说仍然是个大问题。接口名称强制实现者保留名称,无论是否有意义......
【解决方案2】:

方法实现与它们实现的接口方法的绑定是通过方法签名完成的,即名称和参数列表。使用方法Register 实现接口的类必须具有具有相同签名的方法Register。尽管 C# 允许您使用不同的 Register 方法作为显式实现,但在这种情况下,更好的方法是使用 Bridge Pattern,它允许您将接口“连接”到具有不匹配方法签名的实现:

interface IMyInterface {
    void Register(string name);
}

class MyImplementation {
    public void RegisterName(string name) {
        // Wrong Register
    }
    public void RegisterName(string name) {
        // Right Register
    }
}

桥接类将MyImplementationIMyInterface“解耦”,让您可以独立更改方法和属性的名称:

class MyBridge : IMyInterface {
    private readonly MyImplementation impl;
    public MyBridge(MyImplementation impl) {
        this.impl = impl;
    }
    public void Register(string name) {
        impl.RegisterName();
    }
}

当对桥的一侧进行更改时,您需要在桥中进行相应的更改才能恢复正常运行。

【讨论】:

  • 好的,但是正如您所看到的,使用网桥,您不会更改调用方法的名称。在界面中它被称为“注册”,它在网桥中具有相同的名称。我想要的是用不同的名字来实现它。
  • @SuperJMN 桥让MyImplementation 假装它实现了IMyInterface 而没有实际实现它。桥用匹配的名称实现接口以保持 C# 快乐,但实现的“有效负载”逻辑来自 MyImplementation 类。桥接类只是转发调用,而MyImplementation 完成所有工作并保持所有状态。
猜你喜欢
  • 2017-12-19
  • 2011-12-13
  • 1970-01-01
  • 2016-07-23
  • 1970-01-01
  • 2015-03-23
  • 1970-01-01
  • 1970-01-01
  • 2011-07-26
相关资源
最近更新 更多