在 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、AMyClass
或 IMyClass
类型进行分组。这看起来真的很草率,特别是如果我想为不同类型的 IMyClass
创建另一个 abstract
基础 class。在那种情况下,现在将公开 2 个抽象 classes,我不希望其他项目使用它们。
有没有办法阻止其他项目使用抽象 classes,或者它只是放在项目文档中并依赖于 荣誉系统 的种类?
这取决于你想要什么。您想禁止程序集外的客户端代码 all 使用基 abstract
class 吗?或者您只是想防止从此类代码继承它?
后者可以简单地通过构造函数internal
来实现。这可以防止程序集之外的任何代码继承它,因为它们无权访问构造函数。 (请注意,对于非 abstract
classes,您还可以通过构造函数 protected
或 private
来阻止直接实例化......显然没有必要使用 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。
我觉得这个问题可能是主观的,但我很好奇。
在 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、AMyClass
或 IMyClass
类型进行分组。这看起来真的很草率,特别是如果我想为不同类型的 IMyClass
创建另一个 abstract
基础 class。在那种情况下,现在将公开 2 个抽象 classes,我不希望其他项目使用它们。
有没有办法阻止其他项目使用抽象 classes,或者它只是放在项目文档中并依赖于 荣誉系统 的种类?
这取决于你想要什么。您想禁止程序集外的客户端代码 all 使用基 abstract
class 吗?或者您只是想防止从此类代码继承它?
后者可以简单地通过构造函数internal
来实现。这可以防止程序集之外的任何代码继承它,因为它们无权访问构造函数。 (请注意,对于非 abstract
classes,您还可以通过构造函数 protected
或 private
来阻止直接实例化......显然没有必要使用 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.
由于创建基础 class internal
会阻止您创建派生 class public
,因此您的图书馆的客户将无法创建直接派生class也行。所以你必须在一些 public class 中有一个 public 工厂方法,其中 returns public 接口而不是派生的 class。