C# 中的内部与公共

Posted

技术标签:

【中文标题】C# 中的内部与公共【英文标题】:internal vs public in C# 【发布时间】:2011-05-10 01:58:04 【问题描述】:

我想知道publicinternal 可见性修饰符之间的区别。

我们什么时候应该在课堂上使用internal,什么时候应该使用public?我对何时应该使用 publicinternal 感到困惑。

我读到internal可以通过程序集访问,而public也可以通过程序集使用。那么区别在哪里呢?

【问题讨论】:

【参考方案1】:

两者在技术上没有区别。在 C# 中,public 的意思是“任何可以看到该类的人都可以访问”;将内部类设为公共成员并不会使该成员更易于访问。

另一种说法是:假设我们将成员标记为内部,然后决定将类公开而不是内部。我们是否必须将成员从 internal 更改为 public 才能使类起作用?如果答案是“是”,那么它首先应该是公开的。

最后,语言设计的其他方面鼓励您以这种方式思考公共。例如:

internal interface I 

  void M();

internal sealed class C : I

  public void M()  ... 

尽管 I 和 C 都是内部的,但该语言要求 M 是公共的才能实现 I.M.

【讨论】:

【参考方案2】:

internal 在编写单元测试时也很有用。 InternalsVisibleTo 属性允许您的测试程序集访问代码程序集中的内部方法。也就是说,您可以在不使用反射的情况下测试对外界来说是私有的方法。

【讨论】:

【参考方案3】:

internal 在您想要在 DLL 内部而不是外部声明成员或类型时很有用。

通常,当您将成员声明为public 时,您可以从其他 DLL 访问该成员。但是,如果你需要在你的类库中声明一些东西是公开的,你可以将它声明为internal

在正式定义中:内部成员仅在当前程序集中可见。

【讨论】:

【参考方案4】:

public 在任何地方都可见。

internal 仅在程序集中可见。

您倾向于仅使用 internal 来保护内部 API。例如,您可以公开一个方法的多个重载:

public int Add(int x, int y)
public int Add(int x,int y, int z)

两者都调用内部方法:

internal int Add(int[] numbers)

然后,您可以对方法进行大量复杂化处理,但使用可以帮助程序员正确调用方法的外观方法“保护”它。 (例如,带有数组参数的实现方法可能有任意的取值限制。)

另外值得注意的是,使用反射,任何和所有方法都可以调用,而不管它们的可见性如何。另一个“黑客”控制/获得对内部隐藏 API 的访问。

【讨论】:

在内部类中我可以声明公共方法吗..? 否,因为这会导致冲突。编译器会告诉你这个并且编译失败。 @Program.X:实际上,你可以,但编译器不会告诉你任何事情。 其实我是来谷歌搜索这是否真的是一个功能。想象一下创建类internal 和所有方法public。如果您需要更高的知名度,您可以再次将整个班级设置为public。但我不确定它是否打算以这种方式使用。所以我继续谷歌搜索... edit 等等,同一主题:***.com/questions/9302236/…【参考方案5】:

一般而言,public 方法应满足非常高的稳健性标准(不会因输入错误而崩溃或损坏数据)和安全意识(不允许意外输入触发漏洞利用)。但是对于internalprotectedprivate 方法,遵循更宽松的标准通常是合理的,因为可以完全控制每种方法可以接收的输入。

由于传递给public 方法的参数(可能来自外部源)被认为不如从自己的程序集中接收的参数可信,标记为public 的方法通常被代码分析器 区别对待strong> 与标记为internal 的其他方法相同。例如,对于public 方法,分析器可能会警告您检查该方法的参数是否为空。使用internal 方法,可以将分析器配置为对null 检查不那么严格。或者分析器可以通过对程序集的所有源文件进行流分析来自行确定null 永远不会作为参数传递给特定方法,从而确定不需要检查如果参数是null。还有许多其他分析器以不同方式处理 publicinternal 方法的示例。

通过使用正确的访问修饰符正确标记类、方法、属性、字段、接口等,您可以正确地向代码分析器发出您的意图信号,然后分析器可以作为回报给您更多相关的警告消息和建议。

【讨论】:

【参考方案6】:

Public 也可以在程序集之外访问。因此,当您有一个不应访问的类时,程序集中的每个类都应该能够访问它,那么 internal 是正确的。如果您需要外部访问,请使用 public。

【讨论】:

【参考方案7】:

此外,如果用于 WPF 中的 DataBinding,标记为 internal 的属性将抛出 BindingExpression path error。所以那些必须是 public 才能正常工作,即使 DataBinding 发生在同一个程序集中。

【讨论】:

【参考方案8】:

如果你可以从外部引用汇编,你就有了内部类和公共类的范围

【讨论】:

以上是关于C# 中的内部与公共的主要内容,如果未能解决你的问题,请参考以下文章

C#中的访问修饰符

Web 应用程序中的方法应该是公共的还是内部的?

C# 基础 访问修饰符ref与out标志枚举等等

C#中的“公共无效”函数

C#中CLR(公共语言运行时)与IL(中间代码)

Java2C#翻译:C#接口中的公共方法