[英]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..
我的代码可以有两种用户。
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, 好,
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_A
和IDerived_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_A
或IDerived_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_A
和I_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
. 现在可以请求您的库代码中的类来实现
ICore
和INonCore_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.