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

Limiting visibility of abstract base classes in C#

我觉得这个问题可能是主观的,但我很好奇。

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

public interface IMyClass {
    ...
}

IMyClass 实现的任何通用功能然后在同一包 abstract class 中的私有 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 种方式对子 classes、AMyClassIMyClass 类型进行分组。这看起来真的很草率,特别是如果我想为不同类型的 IMyClass 创建另一个 abstract 基础 class。在那种情况下,现在将公开 2 个抽象 classes,我不希望其他项目使用它们。

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

这取决于你想要什么。您想禁止程序集外的客户端代码 all 使用基 abstract class 吗?或者您只是想防止从此类代码继承它?

后者可以简单地通过构造函数internal来实现。这可以防止程序集之外的任何代码继承它,因为它们无权访问构造函数。 (请注意,对于非 abstract classes,您还可以通过构造函数 protectedprivate 来阻止直接实例化......显然没有必要使用 abstract,因为 class 无论如何都不能直接实例化)。

如果是前者,虽然您认为 C# 没有 Java 的 "package" 概念是正确的,但与 [=40= 相比,这限制了访问限制的可能性],你可以靠近

派生的 class 不得比其基础 class 更容易访问。这意味着 public class 的基数 class(abstract 或其他)本身必须是 public.

但是您可以在 C# 中执行与在 Java 中所做的相同类型的基于接口的实现隐藏,方法是使您的 abstract class internal(即 C# 中 class 的默认访问权限),然后 class 也继承了它 internal,同时仍然保留那些 classes 实现的接口 public,它为使用库的客户端代码提供了一种访问 class.

的 public 功能的方法

由于创建基础 class internal 会阻止您创建派生 class public,因此您的图书馆的客户将无法创建直接派生class也行。所以你必须在一些 public class 中有一个 public 工厂方法,其中 returns public 接口而不是派生的 class。