2

this is an issue ive been faced with countless number of times.. consider..

[public/private] interface IBase
{
    void DoCore();
}

public interface IDerived_A : IBase
{
    void Do_A();
}
public interface IDerived_B : IBase
{
    void Do_B();
}

here i have 2 useful interfaces that provide some common functionality (provided by the IBase interface), plus some other functionality unique to either of them.. c# forces me to declare IBase as public (the same visibility as the inheriting interfaces).. however, the IBase interface is visible to everyone.. there is no need for anyone else to use this interface.. ppl only need to access the IDeriver_X interfaces.. how can i hide the IBase interface from the users of my code? there can be two kinds of users of my code..

  1. code in the same namespace / assembly accessing IDerived_X..
  2. code in a separate project referencing the assembly containing IDeriver_X..

ps.. i hate making more interfaces public than is neccessary (neccessary means only those interfaces that ppl will use directly).. ps2.. i face the same dilemma with classes..

EDIT:

i have a feeling that the question was misinterpreted a bit.. for that im posting a clarification.. the issue isnt just related to interfaces.. it bugs me about classes too.. consider the following code..

public abstract class Vehicle
{
    // generic vehicle functionality
}
public Car : Vehicle
{
    // functionality specific to cars
}
public Truck : Vehicle
{
    // functionality specific to trucks
}

Car and Truck are the ONLY two kinds of objects im allowing the users of my code to use.. to make my job easier, and to avoid dupilcation of code, ive moved the common code to the Vehicle abstract class.. but that doesnt mean its ok for the user to store references to cars or trucks in vehicle variables.. from the perspective of the users, my code should only expose cars and trucks (and not vehicles or engines or whatever base classes i used internally to avoid code duplication).. specifically, im looking for a technique that allows me to expose complete cars and trucks but not any other incomplete building blocks like vehicles or engines.. the problem is, c# doesnt let me make the base classes private if the derived class is public.. does that make more sense? =)

4

2 回答 2

3

出色地,

  • 要么你的子接口派生自基础是有道理的
  • 或子接口的用户不应访问基础 API

在第一种情况下,API IDerived_A 的使用者可以访问 IBase 是合理的。在第二个中,不要从基础 IBase 派生

其他任何事情都是在调整 OOP。

作为您的接口的使用者,我同时获得了 IBase 和 IDerived_A,因此我可以访问 IBase 是合理的

于 2013-01-12T19:59:47.620 回答
1

我不确定您要在这里表达什么(因此对您的完整场景的描述可能会有所帮助)。如果您的IDerived_AIDerived_B接口 是IBase,您的客户端代码需要能够访问DoCore. 并且拥有IBasepublic 将允许您概括在继承IDerived_A或的类型上相同的功能IDerived_B

如果您只是想避免在其中重复方法定义,IDerived_A但从I_Derived_BIBase的继承不是建模 IS A 关系(即 I_Derived_A 和 I_Derived_B 不需要在层次结构中直接相关,而只是在它们之间共享一些功能),您可能应该只需创建单独的接口,它们之间没有层次关系,如下所示:

public interface ICore 
{
    void DoCore()
}

public interface INonCore_A // no more inheritance
{
    void Do_A();
}

public interface INonCore_B 
{
    void Do_B();
}

现在可以请求您的库代码中的类来实现ICoreINonCore_A/BICore它本身可能仍然需要公开(除非您希望 DoCore 方法本身仅对您的库代码可见),但您可以通过使用ICore.

在第二种情况下,您失去的是一种告诉您的客户端代码实现INonCore_A 需要您也实现的方式ICore。例如,该功能存在于 scala 编程语言中,但不存在于 C# 中。如果它存在,你可以说:

// warning: non-existing c# syntax. Does not compile
    public interface INonCore_A {
        self: ICore => // this is scala syntax, does not work in c#
                       // it means "anyone who implements INonCore_A must 
                       // also implement ICore
            void Do_A();
    }

如前所述,由于这在 c# 中不起作用,因此取决于文档和程序员的纪律,以确保无论谁实现INonCore_A和 B 也实现ICore

于 2013-01-12T20:21:09.303 回答