在我们的一个项目中,有很多代码看起来像这样:
internal static class Extensions
{
public static string AddFoo(this string s)
{
if (s == null)
{
return "Foo";
}
return $({s}Foo);
}
}
除了“以后更容易将类型公开”之外,还有其他明确的原因吗?
我怀疑它只在非常奇怪的边缘情况下(在Silverlight反射)或根本不重要。
出于与在任何其他类中使用公共方法相同的原因——因此它们对包含类型外部是公共的。
类型的访问修饰符与其成员的访问修饰符完全没有关系。这两个决定是完全独立的。
仅仅因为类型和成员的修饰符的某些组合产生了看似相同的结果(或者其他人称之为“有效”)并不意味着它们在语义上是相同的。
实体的本地访问修饰符(在代码中声明)和它的全局有效访问级别(通过包含链评估)也是完全不同的东西。一间上了锁的大楼里的开放式办公室仍然是开放的,即使你不能从街上真正进入它。
不要考虑最终结果。首先,想想你在当地需要什么。
公众的公众:经典的情况。
Public的Internal:类型是Public,但是你想在程序集中获得一些半合法的访问权限来做一些古怪的事情。
内部的公共:你隐藏了整个类型,但在程序集中它有一个经典的公共表面
内部的内部:我想不出任何现实世界的例子。也许很快就会成为公众的内部信息?
内部的公众vs内部的内部是一个虚假的困境。这两个词的意思完全不同,应该在各自的情况下使用,不能重叠。
我今天真的很纠结这个问题。到目前为止,如果类是内部的,我会说方法都应该被标记为内部的,并且会认为其他任何东西都只是糟糕的编码或懒惰,特别是在企业开发中;然而,我必须子类化一个公共类并重写它的一个方法:
internal class SslStreamEx : System.Net.Security.SslStream
{
public override void Close()
{
try
{
// Send close_notify manually
}
finally
{
base.Close();
}
}
}
方法必须是公共的,这让我想到,将方法设置为内部没有逻辑意义,除非它们真的必须是,就像Eric Lippert说的那样。
直到现在,我从来没有真正停下来思考过这个问题,我只是接受了它,但在阅读了Eric的帖子后,它真的让我思考,经过很多深思熟虑后,它有很多意义。
出于与在任何其他类中使用公共方法相同的原因——因此它们对包含类型外部是公共的。
类型的访问修饰符与其成员的访问修饰符完全没有关系。这两个决定是完全独立的。
仅仅因为类型和成员的修饰符的某些组合产生了看似相同的结果(或者其他人称之为“有效”)并不意味着它们在语义上是相同的。
实体的本地访问修饰符(在代码中声明)和它的全局有效访问级别(通过包含链评估)也是完全不同的东西。一间上了锁的大楼里的开放式办公室仍然是开放的,即使你不能从街上真正进入它。
不要考虑最终结果。首先,想想你在当地需要什么。
公众的公众:经典的情况。
Public的Internal:类型是Public,但是你想在程序集中获得一些半合法的访问权限来做一些古怪的事情。
内部的公共:你隐藏了整个类型,但在程序集中它有一个经典的公共表面
内部的内部:我想不出任何现实世界的例子。也许很快就会成为公众的内部信息?
内部的公众vs内部的内部是一个虚假的困境。这两个词的意思完全不同,应该在各自的情况下使用,不能重叠。
I think I have an additional opinion on this. At first, I was wondering about how it makes sense to declare something to public in an internal class. Then I have ended up here, reading that it could be good if you later decide to change the class to public. True. So, a pattern formed in my mind: If it does not change the current behavior, then be permissive, and allow things that does not makes sense (and does not hurt) in the current state of code, but later it would, if you change the declaration of the class.
是这样的:
public sealed class MyCurrentlySealedClass
{
protected void MyCurretlyPrivateMethod()
{
}
}
According to the "pattern" I have mentioned above, this should be perfectly fine. It follows the same idea. It behaves as a private method, since you can not inherit the class. But if you delete the sealed constraint, it is still valid: the inherited classes can see this method, which is absolutely what I wanted to achieve. But you get a warning: CS0628, or CA1047. Both of them is about do not declare protected members in a sealed class. Moreover, I have found full agreement, about that it is senseless: 'Protected member in sealed class' warning (a singleton class)
因此,在这个警告和相关的讨论之后,我决定在一个内部类中使所有内容都变得内部或更少,因为它更符合那种思维方式,而且我们不会混合不同的“模式”。