限制C#中抽象基类的可见性

时间:2015-03-16 03:04:44

标签: java c# interface abstract privacy

我觉得这个问题可能偏离主题,但我很好奇。

在java中,我习惯使用包private和public来隐藏其他包中的类型实现。我通常有一个interface,例如:

public interface IMyClass {
    ...
}

IMyClass实现的任何常见功能都在同一个包中的私有abstract class中定义

abstract class AMyClass implements IMyClass {
    public AMyClass(...)
    ...
}

然后派生类型为public,并且也在IMyClass

中定义
public class CustomMyClass extends AMyClass {
    public CustomMyClass(...){
        super(...) 
        ...
}

在c#中我想遵循相同的结构,但当你扩展abstract class时,它必须是public。我唯一能阻止其他软件包扩展AMyClass或使用其内部函数的方法是使其访问级别为internal

public interface IMyClass{
    ...
}
...
public class AMyClass : IMyClass {
    internal AMyClass(...)
    ...
}
...
public class CustomMyClass : AMyClass {
    public CustomMyClass(...) : base(...){
        ...
}

但是这种风格仍然允许其他c#项目以2种方式对子类AMyClassIMyClass类型进行分组。这似乎非常草率,特别是如果我想为不同类型的abstract创建另一个IMyClass基类。在这种情况下,现在将公开2个抽象类,我不希望其他项目使用。

有没有办法阻止其他项目使用抽象类,或者它只是放在项目文档中并依赖于各种荣誉系统的东西?

1 个答案:

答案 0 :(得分:2)

这取决于你想要什么。您是否希望通过程序集外的客户端代码禁止所有使用基础abstract类?或者你只是想阻止它从这样的代码继承?

后者可以通过制作构造函数internal来实现。这可以防止程序集外的任何代码继承它,因为它们无法访问构造函数。 (请注意,对于非abstract类,您还可以通过构造函数protectedprivate来阻止直接实例化...显然,abstract无需执行此操作因为无论如何都无法直接实例化。)

如果前者是正确的,那么C#没有Java#" package"的概念,这限制了与Java相比可访问限制的可能性,你可以来关闭。

派生类不能比其基类更易于访问。这意味着abstract类的基类(public或其他)本身必须为public

但您可以通过制作abstractinternal(即默认访问权限)来完成与C#中相同类型的基于接口的实现 - 隐藏在C#中C#中的类,然后是一个继承它的类internal,同时仍然留下一个接口,这些类实现public,它使用库提供客户端代码来访问类的公共特性。

由于使基类internal阻止您创建派生类public,因此您的库的客户端无法直接创建派生类的实例。因此,您必须在某个公共类中使用公共工厂方法,该方法返回公共接口而不是派生类。