C# 为什么在内部类中使用公共方法?

C# 为什么在内部类中使用公共方法?,c#,scope,public,internals,C#,Scope,Public,Internals,我们的一个项目中有很多代码如下所示: internal static class Extensions { public static string AddFoo(this string s) { if (s == null) { return "Foo"; } return $({s}Foo); } } 除了“以后公开该类型更容易”之外,还有其他明确的原因吗 我怀疑它只在非常奇怪

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

internal static class Extensions
{
    public static string AddFoo(this string s)
    {
        if (s == null)
        {
            return "Foo";
        }

        return $({s}Foo);
    }
}
除了“以后公开该类型更容易”之外,还有其他明确的原因吗


我怀疑它只在非常奇怪的边缘情况下(Silverlight中的反射)才起作用,或者根本不起作用。

internal
表示只能从同一程序集中访问该成员。该程序集中的其他类可以访问
内部公共
成员,但不能访问
私有
受保护的
成员,
内部
或不访问。

我怀疑“以后更容易将类型公开”是这样吗

作用域规则意味着该方法将仅作为
内部
可见-因此,该方法是否标记为
公共
内部
,实际上并不重要


我想到的一种可能性是,该类是公共的,后来改为
内部的
,开发人员没有费心去更改所有的方法可访问性修饰符。

同样,公共方法将真正标记为内部的,因为它在内部类中,但它有一个advantaje(如您所述),如果要将类标记为public,则必须更改较少的代码。

我经常将内部类中的方法标记为public,而不是internal。a)这并不重要,b)我使用internal表示该方法是有意内部的(我不想在公共类中公开此方法是有原因的。因此,如果我有一个内部方法,我必须在将其更改为公共类之前理解它是内部的原因,而如果我在内部类中处理公共方法,我必须考虑为什么该类是内部的,而不是为什么每个类都是内部的。)方法是内部的。

如果类是
内部的
,则从可访问性的角度来看,标记方法
内部的
还是
公共的
,都无关紧要。但是,如果类是
公共的
,使用您将使用的类型仍然是好的

虽然有人说这简化了从
internal
public
的转换。它也是该方法描述的一部分。
internal
方法通常被认为对不受限制的访问是不安全的,而
public
方法被认为是(大部分)免费游戏


通过像在
public
类中一样使用
internal
public
,您可以确保传达所需的访问方式,同时也简化了将来使类
公开所需的工作。

在某些情况下,内部类型也可能实现公共交互ce,这意味着在该接口上定义的任何方法仍然需要声明为公共的。

更新:这个问题是。感谢您提出的好问题

在这个问题上,甚至在编译器团队内部也有相当多的争论

首先,理解规则是明智的。类或结构的公共成员是可以访问包含类型的任何对象的成员。因此,内部类的公共成员实际上是内部成员

那么,现在,给定一个内部类,您希望在程序集中访问的成员应该标记为public还是internal

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

我使用“public”表示“此成员不是实现细节”。受保护的成员是一个实现细节;要使派生类正常工作,需要它的某些方面。内部成员是一个实现细节;此程序集内部的其他方面需要该成员才能正常工作。公共成员说此成员表示此对象提供的关键、有文档记录的功能

基本上,我的态度是:假设我决定把这个内部类变成一个公共类。为了做到这一点,我只想改变一件事:类的可访问性。如果把一个内部类变成一个公共类意味着我还必须把一个内部成员变成一个公共成员,那么这个成员就是其中的一部分课程的公共表面积,它本来应该是公共的

其他人不同意。有一个团队表示,他们希望能够浏览成员的声明,并立即知道是否只从内部代码调用该声明


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

我今天真的很难做到这一点。直到现在,我都会说方法都应该标记为public如果类是
internal
的话,我会使用
internal
,如果类是
internal
的话,我会考虑任何其他简单的糟糕的编码或懒惰,特别是在企业开发中;然而,我不得不将类a
public
划分为子类,并覆盖它的一个方法:

internal class SslStreamEx : System.Net.Security.SslStream
{
    public override void Close()
    {
        try
        {
            // Send close_notify manually
        }
        finally
        {
            base.Close();
        }
    }
}
该方法必须是
public
,这让我想到,除非它们真的必须是,否则将方法设置为
internal
是没有逻辑意义的,正如Eric Lippert所说


到目前为止,我从未真正停下来思考过,我只是接受了它,但在阅读了Eric的帖子后,它真的让我思考了很多,经过深思熟虑,它是很有意义的。

这确实有很大的不同。 在我们的项目中,我们制作了许多内部类,但是我们在另一个程序集中进行单元测试,在我们的程序集信息中,我们使用InternalsVisibleTo允许UnitTest程序集调用内部类。 我注意到,如果内部类有一个内部构造函数,我们就无法在单元测试程序集中使用Activator.CreateInstance创建实例
public sealed class MyCurrentlySealedClass
{
    protected void MyCurretlyPrivateMethod()
    {
    }
}