为什么C#没有包级私有?

19

我正在学习C#,来自Java世界,有点困惑的是C#没有"package private"。大多数评论都是"你不能这样做;这个语言不是这样设计的"。我还看到了一些解决方法,包括internalpartial,还有注释说这些解决方法违反了语言的设计。

C#为什么会被设计成这样?另外,如果我想做以下操作:我有一个Product类和一个ProductInstance类。我只想通过Product类中的工厂方法创建ProductInstance对象。在Java中,我会将ProductInstance放在与Product相同的包中,但使用package private构造函数,以使只有Product类才能访问它。这样,任何想要创建ProductInstance对象的人都只能通过Product类中的工厂方法来创建。我该如何在C#中实现相同的功能?


2
将Product类的构造函数设置为私有,然后创建一个公共静态函数来返回Product实例,例如:var p = Product.GetProductInstance。 - Jeremy Thompson
4
看到这些答案,我没有看到为什么的答案。我认为在一个方法被设计成只由少数“友好”类(参见C++中的friend关键字)使用时,将其设置为internal是一种很大的代码异味。我不希望将我的应用程序拆分成数百个dll来防止异味访问,也不喜欢将我的详细实现公开(基本上对整个dev团队公开)。我应该编写具有十个子类的巨型类以克服这个限制吗? - PPC
2个回答

37

internal 是你需要的。它表示该成员可被同一程序集中的任何类访问。在这种情况下(Product和ProductInstance),使用它是没有问题的,并且正是为此目的而设计的之一。C#选择不使命名空间有意义——它们用于组织,而不是像Java中的包私有那样确定类型能看到彼此。

partialinternal 包私有完全不同。它只是将一个类的实现分割成多个文件的一种方式,并加入了一些可扩展性选项。


那我只需要将 ProductInstance 的构造函数标记为 internal 吗? - Vivin Paliath
@Vivin,是的,很可能还包括类。 - Kirk Woll
不,仅为一个工厂类创建一个程序集是错误的建议。拥有数百个程序集会使项目难以管理。 - miguel
@miguel,你把我的回答混淆成建议为每个类创建单独的程序集,这让我感到非常惊讶。 - Kirk Woll
OP的目标:创建ProductInstance的唯一方法是通过Product.factory。你的答案是:使用internal。但是,internal仍然允许其他程序集中的其他类通过其构造函数创建ProductInstance。因此,你的答案只有在ProductProductInstance位于它们自己的程序集中时才有意义。 - miguel
显示剩余2条评论

9

在Java中,包的存在方式与实际情况并不完全相同。命名空间用于组织代码和防止命名冲突,但不用于访问控制。项目/程序集可用于访问控制,但您无法像使用包一样嵌套项目/程序集。

使用 internal 将一个项目的成员隐藏在另一个项目中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接