为什么在公共课堂上使用公共方法?

我们的一个项目中有很多代码,如下所示:

internal static class Extensions { public static string AddFoo(this string s) { if (!string.IsNullOrEmpty(s)) return s + "Foo"; return "Foo"; } } 

有没有明确的理由,除了“稍后公布types更容易”之外呢?

我怀疑它只是在非常奇怪的边缘情况下(Silverlight中的reflection)或根本不重要。

更新:这个问题是我的博客在2014年9月的主题 。 感谢您的好问题!

即使在编译器团队内部,对这个问题也有相当多的争论。

首先,理解规则是明智的。 类或结构的公共成员是任何可以访问包含types的成员 。 所以一个内部阶级的公共成员是有效的内部的。

那么现在,如果有内部课程,你希望在大会上访问的成员是否应该被标记为公开或内部?

我的意见是:将这些成员标记为公开。

我使用“公共”来表示“这个成员不是一个实现细节”。 受保护的成员是实现细节; 有一些关于它将需要做派生类的工作。 内部成员是一个实现细节; 该组件内部的其他内容需要该成员才能正常工作。 一个公共成员说:“这个成员代表了这个对象提供的关键,logging的function。”

基本上,我的态度是:假设我决定把这个内部阶级变成公开课。 为了做到这一点,我想改变一件事 :class级的可达性。 如果把内部阶级变成公共阶级,就意味着我也要把内部成员变成公众成员,那么这个成员就是这个阶级的公共场所的一部分,应该是公开的。

其他人不同意。 有一个团队说,他们希望能够看一下会员的声明,并立即知道是否只会从内部代码中调用。

不幸的是,这并不总是很好的工作。 例如,实现内部接口的内部类仍然必须将实现成员标记为公开的,因为它们是类的公共表面的一部分

如果这个类是internal ,那么从可访问性的angular度来看,无论是internal还是public ,都是无关紧要的。 但是,如果课堂是public那么使用你使用的types也是很好的。

虽然有人说这简化了从internalpublic转变。 它也作为方法描述的一部分。 Internal方法通常被认为是不安全的访问不安全,而public方法被认为是(大部分)免费游戏。

通过在public课堂中使用internalpublic课程,确保您正在传达预期的访问方式,同时也减轻将来public课程所需的工作量。

我经常把我的方法标记为公开的内部类而不是内部的:a)它并不重要,b)我使用internal来表示这个方法是内在的(我有一些原因,我不想公开这个方法,所以如果我有一个内部方法,我真的必须理解为什么它是内部的,然后再把它改为public,而如果我正在处理一个内部类的公共方法,我真的不得不考虑为什么类是内部的,而不是为什么每个方法都是内部的。

我怀疑“稍后公布这种types会更容易些?” 是吗。

范围规则意味着该方法只能作为internal – 所以这些方法是public还是internal都是无关紧要的。

想到的一个可能性是,这个类公开的,后来被改为internal ,开发人员并没有去更改所有的方法可访问性修饰符。

在某些情况下,也可能是内部types实现了一个公共接口,这意味着在该接口上定义的任何方法仍然需要声明为public。

同样的,公共方法会被标记为内部的,因为它在内部类中,但是它有一个优点(如你所猜),如果你想把类标记为公共的,你必须改变较less的代码。

internal说成员只能从同一个程序集中访问。 该程序集中的其他类可以访问internal public成员,但无法访问privateprotected成员,无论是否为internal成员。

我今天真的很挣扎。 到现在为止,如果这个课程是internal ,那么所有的方法都应该用internal标志来表示,而且在考虑其他的问题时,特别是在企业发展方面,这种方法只是不好的编码或者懒惰。 然而,我不得不子类public类,并重写其方法之一:

 internal class SslStreamEx : System.Net.Security.SslStream { public override void Close() { try { // Send close_notify manually } finally { base.Close(); } } } 

这个方法必须是public ,这让我想到,除非真的必须如此,否则将方法设置为internal是没有任何逻辑的。

到目前为止,我从来没有停下来思考过,我只是接受了,但是在阅读Eric的post之后,真的让我思考,经过大量的讨论,这很有道理。

有一个区别。 在我们的项目中,我们做了很多类,但是我们在另一个程序集中进行了unit testing,在我们的程序集信息中我们使用了InternalsVisibleTo来允许UnitTest程序集调用内部类。 我注意到如果内部类有一个内部构造函数,我们无法使用unit testing程序集中的Activator.CreateInstance创build实例。 但是,如果我们将构造函数更改为public,但类仍然是内部的,它就可以正常工作。 但我想这是一个非常罕见的情况(就像Eric在原文中所说:Reflection)。