C# 中的内部与公共
Posted
技术标签:
【中文标题】C# 中的内部与公共【英文标题】:internal vs public in C# 【发布时间】:2011-05-10 01:58:04 【问题描述】:我想知道public
和internal
可见性修饰符之间的区别。
我们什么时候应该在课堂上使用internal
,什么时候应该使用public
?我对何时应该使用 public
或 internal
感到困惑。
我读到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
方法应满足非常高的稳健性标准(不会因输入错误而崩溃或损坏数据)和安全意识(不允许意外输入触发漏洞利用)。但是对于internal
、protected
和private
方法,遵循更宽松的标准通常是合理的,因为可以完全控制每种方法可以接收的输入。
由于传递给public
方法的参数(可能来自外部源)被认为不如从自己的程序集中接收的参数可信,标记为public
的方法通常被代码分析器 区别对待strong> 与标记为internal
的其他方法相同。例如,对于public
方法,分析器可能会警告您检查该方法的参数是否为空。使用internal
方法,可以将分析器配置为对null
检查不那么严格。或者分析器可以通过对程序集的所有源文件进行流分析来自行确定null
永远不会作为参数传递给特定方法,从而确定不需要检查如果参数是null
。还有许多其他分析器以不同方式处理 public
和 internal
方法的示例。
通过使用正确的访问修饰符正确标记类、方法、属性、字段、接口等,您可以正确地向代码分析器发出您的意图信号,然后分析器可以作为回报给您更多相关的警告消息和建议。
【讨论】:
【参考方案6】:Public 也可以在程序集之外访问。因此,当您有一个不应访问的类时,程序集中的每个类都应该能够访问它,那么 internal 是正确的。如果您需要外部访问,请使用 public。
【讨论】:
【参考方案7】:此外,如果用于 WPF 中的 DataBinding,标记为 internal
的属性将抛出 BindingExpression path error
。所以那些必须是 public
才能正常工作,即使 DataBinding 发生在同一个程序集中。
【讨论】:
【参考方案8】:如果你可以从外部引用汇编,你就有了内部类和公共类的范围
【讨论】:
以上是关于C# 中的内部与公共的主要内容,如果未能解决你的问题,请参考以下文章