内部类的公共方法和内部方法的区别

90
internal class Foo
{
  public void Fee()
  {
    Debug.WriteLine("Fee");
  }

  internal void Fi()
  {
    Debug.WriteLine("Fi");
  }
}

我认为由于整个类已经是内部的,因此Fee()和Fi()同样可以被访问。我有忽略什么吗?在这种情况下选择public或internal方法是否有任何理由?


2
@EricLippert今天发表了他的观点。http://ericlippert.com/2014/09/15/internal-or-public/#more-2353 - ScottS
7个回答

101

internal class Foo 声明将会覆盖 public void Fee() 方法的可访问性,使其变为 internal。

在这种情况下,在方法上使用 internal 和 public 将会有相同的效果。我之所以在这种情况下选择公共方法而不是内部方法,只是为了方便在以后的版本中过渡到公共类(如果您选择这样做)。


37

这个答案唯一缺少的是为什么要这样做?

有些库有很多类,不是为库的使用者所接触的,但它们必须继承标记为公共的接口。例如,我有一个库,其中一个类继承了IComparer接口,但它只在内部使用,我不想在我的库的公共方面添加混乱。如果我将实现的Compare函数标记为internal,则编译器会抱怨我没有实现IComparer接口。

那么,如何成功实现接口并同时防止其在库的公共方面被访问?将类标记为internal,但将实现的函数标记为public。


30

实际上,如果你使用反射,会有很大的区别;特别是在Silverlight中,即使你本来就有权限访问,如果你试图通过反射访问内部方法,它也可能会出现问题。我曾经遇到过这种情况,必须将一个方法公开才能让代码在Silverlight上运行,尽管它在常规.NET上可以正常工作。

在常规.NET中,你可能会发现与部分信任相关的类似情况。


3
这些都是我一直感兴趣的具体细节。不过,通常情况下,如果有人使用反射来访问我的类中隐藏的成员,即使对他们来说很困难,我也不会担心。 - ScottS
1
@ScottS - 有时候你会反思自己的类型 - 即你通常可以访问内部方法的地方,但突然间你无法访问。 - Marc Gravell

11

如果您希望内部类实现接口,则会产生差异。实现某些接口的方法必须是public。


7
您是正确的,Fee和Fi将同样可访问。
根据CSharp语言规范3.0,第3.5.2节:
嵌套成员M在程序P中声明于类型T内,其可访问性域定义如下(注意M本身可能是一个类型): • 如果M的声明可访问性为public,则M的可访问性域即为T的可访问性域。
因此,即使Fee声明为public,它也将与Foo(即internal)一样可访问。

3
根据 msdn文档 ,你的Foo类在程序集外部是不可访问的,所以将方法标记为internal或public并没有任何区别;即使使用InternalsVisibleTo属性也没有区别。

1
如果一个类是 internal 的,我会只使用内部方法。万一你改变主意并将该类设为 public,你只需进行文本替换即可完成。

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