接口访问修饰符困境

Posted

技术标签:

【中文标题】接口访问修饰符困境【英文标题】:Interface access modifier dilemma 【发布时间】:2018-06-13 05:52:39 【问题描述】:

在我的 C# 程序中,我有几个自己的接口,我希望将它们保留在我的程序集内部。

internal interface Doable 
    void DoSomething ();


internal interface Informable 
    void SomethingHappened (Doable obj);

我也有一个不能是内部的抽象类,它像这样抽象地实现了两个接口。

public abstract class MyAbstractClass : Doable, Informable 
    internal abstract void DoSomething ();
    internal abstract void SomethingHappened (Doable obj);

    // Other methods

但是,当我这样做时,我收到一个错误,即 MyAbstractClass 没有实现 Doable.DoSomething()(以及 SomethingHappened(Doable obj))。

我可以将抽象实现的 DoSomething() 的访问修饰符更改为 public(但是我一开始不想这样做),但是 SomethingHappened(Doable obj) 是另一回事:它会抱怨(这是正确的)接口Doable 是内部的(因此此方法可能没有public 访问修饰符)。

我进退两难了。我基本上希望在程序集中的所有类中保留接口及其所有具体实现的方法,而外部调用者不知道它们的存在。

想知道如何解决这个问题?

【问题讨论】:

您可以使用显式接口实现(docs.microsoft.com/en-us/dotnet/csharp/programming-guide/…)并将方法调用转发到内部抽象方法。 接口是合约。要么将它们公开,要么不签署合同(不要告诉调用者,根本不要将它们添加到公共类)。 public classinternal abstract 成员是代码味道。 @Servy 答案是一个很好的答案,另一个是公开 public MyPublicAbstractClass 包装(不要继承!)一些 internal MyInternalAbstractClass @Sinatr,合同也可以是内部的,没有正当理由不这样做。我不同意代码异味部分:有一个非常有效的用例,当一个对象的更改需要在程序集中的多个对象之间传播和级联时,而不会让外人知道这一点。访问修饰符 thingy 不断阻碍这一点。 我的意思是:你为什么要暴露internal的东西(你是通过使用接口来做的)?为什么来电者应该知道呢?看看例如框架,我不记得有一个类实现了这样的 hidden 接口,因为设计是从创建公共接口开始的。相反,您正在尝试创建包含隐藏内容的公共类。为什么?因为一些隐藏方法正在使用公共类的那些隐藏接口方法还是什么?因此,您正试图让该类执行两个角色 = 代码异味。你能告诉我们具体的代码吗?如果你的权利,辩论和辩护会更容易。 【参考方案1】:

与其将接口实现抽象化,不如提供一个具体(显式接口)实现,该实现调用实际完成工作的内部抽象方法。这确保了接口不可公开调用;它只能从当前程序集访问。

【讨论】:

我发誓我首先阅读的答案是“使公共接口继承自内部接口并在公共类中实现该接口”。这部分是改变了还是从未写过? Oo 是否存在问题(如果已更改)? @Sinatr 我没有编辑这个答案,如果这就是你要问的。 void SomethingHappened (Doable obj) 无法重定向到 protected abstract 方法,因为 Doable 参数是 internal。所以实际的方法应该是internal(或private protected)。 @IvanStoev 它必须是内部的。已编辑。【参考方案2】:

你应该使用显式实现;

internal interface IDoable

    void DoSomething();


internal interface Informable

    void SomethingHappened(IDoable obj);

public class MyClass : IDoable, Informable

    void IDoable.DoSomething()
    
        throw new NotImplementedException();
    

    void Informable.SomethingHappened(IDoable obj)
    
        throw new NotImplementedException();
    

【讨论】:

以上是关于接口访问修饰符困境的主要内容,如果未能解决你的问题,请参考以下文章

Java修饰符

java中抽象类与接口中方法访问修饰符问题 (

Java基础-访问修饰符

Java中的修饰符

为啥接口成员没有访问修饰符? [复制]

java访问修饰符