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

Eri*_*ham 231 c# scope public internal

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

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

有没有明确的理由去做"除了以后更容易公开这种类型?"

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

Eri*_*ert 389

更新:这个问题是我2014年9月的博客主题.谢谢你这个好问题!

即使在编译器团队本身内,对这个问题也存在相当大的争议.

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

那么现在,给定一个内部类,您希望在程序集中访问的成员是否应标记为公共或内部?

我的意见是:将此类成员标记为公开.

我使用"public"来表示"此成员不是实现细节".受保护的成员是实现细节; 有一些东西需要它来使派生类工作.内部成员是实现细节; 此程序集内部的其他内容需要该成员才能正常工作.一位公共成员说"这个成员代表了这个对象提供的关键,记录的功能."

基本上,我的态度是:假设我决定将这个内部课程变成公共课.为了做到这一点,我想改变一件事:类的可访问性.如果将内部类转变为公共类意味着我还必须将内部成员转变为公共成员,那么该成员是该类的公共表面区域的一部分,并且它应该首先是公共的.

其他人不同意.有一个特遣队说,他们希望能够看一眼成员的声明,并立即知道是否只能从内部代码调用它.

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

  • 我喜欢这个答案......它非常符合我对编写尽可能自我记录的代码的态度,并且范围是广播意图的好方法,特别是如果您的其他团队成员理解您的惯例. (10认同)
  • +1用于说出我想说的内容,但是比我能够更好地制定它(也用于提高界面角度,但我注意到它只适用于隐式成员实现). (10认同)
  • 从思想的角度来看,你支持"公共"的论点是非常有说服力的.但是,我发现"并不总能很好地......"才能变得特别强大.失去一致性会使任何"一目了然"的好处贬值.以这种方式使用"内部"意味着刻意建立有时是错误的直觉.拥有一个大致正确的直觉是IMO对于编程来说是一件可怕的事情. (8认同)
  • 接口部分很重要-不可能使用内部方法来实现接口方法,它是公共的或显式的接口声明。因此,“公共”一词有两个含义。 (2认同)
  • 博客中的重要一句话:“我的建议是与团队讨论问题,做出决定,然后坚持下去。” (2认同)

Guv*_*nte 15

如果是类internal,从可访问性的角度来看,无论是标记方法internal还是标记,都无关紧要public.但是,如果使用类,那么使用您将使用的类型仍然是好的public.

虽然一些人说,这简化了从过渡internalpublic.它也是该方法描述的一部分.Internal对于不受限制的访问,方法通常被认为是不安全的,而public方法被认为是(大多数)免费游戏.

通过使用internalpublic像在public课堂中一样,您可以确保正在传达预期的访问方式,同时还可以简化public将来创建课程所需的工作.


Ɖia*_*zeƦ 10

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

  • 你是对的,埃里克,这是一个有点废弃的评论。希望我的其余回答有一些用处。我认为埃里克·利珀特的回答正是我想要表达的,但他解释得更好。 (2认同)

Ode*_*ded 8

我怀疑"以后更容易公开这种类型?" 是吗.

范围规则意味着该方法只能被视为internal- 因此方法是否被标记public或无关紧要internal.

想到的一种可能性是该类公开的,后来改为,internal开发人员也没有费心去改变所有方法可访问性修饰符.

  • +1 用于解决明显的“公共课程变成内部课程”的情况。 (2认同)

Tre*_*ley 7

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