简体   繁体   English

隐藏污染代码的基类或接口

[英]Hiding base class or interface from polluting code

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? 在这里,我有2个有用的接口,它们提供一些常用功能(由IBase接口提供),以及它们各自独有的一些其他功能。.c#强制我将IBase声明为public(与继承接口具有相同的可见性)。 ,每个人都可以看到IBase界面。.不需要其他任何人使用。.ppl只需要访问IDeriver_X接口。.我如何向代码用户隐藏IBase接口? there can be two kinds of users of my code.. 我的代码可以有两种用户。

  1. code in the same namespace / assembly accessing IDerived_X.. 同一名称空间/程序集中访问IDerived_X的代码。
  2. code in a separate project referencing the assembly containing IDeriver_X.. 一个单独的项目中的代码,引用包含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.. ps ..我讨厌公开比必要数量更多的接口(必要是指仅ppl将直接使用的那些接口)。ps2 ..我在类方面面临相同的困境。

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? 汽车和卡车是仅有的两种对象,它们允许我的代码的用户使用..使我的工作更轻松,并且避免代码重复,我已将通用代码移至Vehicle抽象类。.但是,这并不意味着用户可以在车辆变量中存储对小汽车或卡车的引用。.从用户的角度来看,我的代码应仅公开小汽车和卡车(而不是小汽车或发动机或我内部使用的任何基类,以避免代码重复) ..具体来说,我正在寻找一种技术,使我可以暴露完整的汽车和卡车,但不能暴露任何其他不完整的构建基块,例如车辆或引擎。.问题是,如果派生类是公共的,则c#不允许我将基类设为私有..这样更有意义吗? =) =)

Well, 好,

  • either it makes sense that your child interfaces are derived from a base 您的子接口是从基础派生的,这很有意义
  • or user of child interfaces should not have access to API of a base 或子接口的用户不应访问基础API

In first case, it is reasonable, that consumer of API IDerived_A has access to IBase. 在第一种情况下,API IDerived_A的使用者可以访问IBase是合理的。 In the second do not dervie from the base IBase 在第二部分中,请勿偏离基础IBase

Anything else, is tweating OOP. 其他任何事情都在调整OOP。

As a consumer of your interface, I am provided with both IBase and IDerived_A, so it is reasonable that I do have access to IBase 作为您接口的使用者,我同时获得了IBase和IDerived_A,因此我可以访问IBase是合理的

I'm not sure what you're trying to express here(so maybe a description of your complete scenario may help). 我不确定您要在此处表达什么(因此,对完整场景的描述可能会有所帮助)。 If your IDerived_A and IDerived_B interfaces ARE IBase s, your client code needs to be able to access DoCore . 如果您的IDerived_AIDerived_B接口是IBase ,则您的客户端代码需要能够访问DoCore And having IBase public would allow you to generalize functionality that works the same on types inheriting either IDerived_A or IDerived_B . 公开使用IBase将使您能够泛化在继承IDerived_AIDerived_B类型上相同的功能。

If you just want to avoid repeating method definitions in IDerived_A and I_Derived_B but inheritance from your IBase is NOT modelling a IS A relationship (ie I_Derived_A and I_Derived_B don't need to be directly related in a hierarchy but are just sharing some functionality between them) you should probably just create separate interfaces with no hierarchical relation between them, like this: 如果您只是想避免在IDerived_AI_Derived_B重复方法定义,但是从您的IBase继承不建模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();
}

now the classes in your library code can be requested to implement both ICore and INonCore_A/B . 现在可以请求您的库代码中的类来实现ICoreINonCore_A/B ICore itself may still need to be public (unless you want the DoCore method itself to be only visible to your library code) but you can sort of "hide" it in your classes by using an explicit interface implementation of ICore . ICore本身可能仍需要公开(除非您希望DoCore方法本身仅对您的库代码可见),但是您可以通过使用ICore的显式接口实现在类中“隐藏”它。

What you lose, in this second case, is a way to tell your client code that implementing INonCore_A requires you to also implement ICore . 在第二种情况下,您所失去的是一种告诉客户端代码实现INonCore_A 要求您还实现ICore That functionality exists for instance in the scala programming language but not in C#. 该功能例如在scala编程语言中存在,但在C#中不存在。 If it existed you could say: 如果存在,您可以说:

// 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();
    }

As said, since this does not work in c#, it is down to documentation and programmer's discipline to make sure that whoever implements INonCore_A and B also implements ICore 如前所述,由于这在c#中不起作用,因此INonCore_A文档和程序员的纪律,以确保实现INonCore_A和B的人也都实现ICore

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM