C# 中“内部”关键字的实际用途

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/165719/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 16:24:28  来源:igfitidea点击:

Practical uses for the "internal" keyword in C#

c#access-modifiersinternals

提问by Alexander Prokofyev

Could you please explain what the practical usage is for the internalkeyword in C#?

你能解释一下internalC# 中关键字的实际用法吗?

I know that the internalmodifier limits access to the current assembly, but when and in which circumstance should I use it?

我知道internal修饰符限制了对当前程序集的访问,但是我应该在什么时候以及在什么情况下使用它?

采纳答案by Ash

Utility or helper classes/methods that you would like to access from many other classes within the same assembly, but that you want to ensure code in other assemblies can't access.

您希望从同一程序集中的许多其他类访问的实用程序或帮助程序类/方法,但您希望确保其他程序集中的代码无法访问。

From MSDN(via archive.org):

来自MSDN(通过 archive.org):

A common use of internal access is in component-based development because it enables a group of components to cooperate in a private manner without being exposed to the rest of the application code. For example, a framework for building graphical user interfaces could provide Control and Form classes that cooperate using members with internal access. Since these members are internal, they are not exposed to code that is using the framework.

内部访问的一个常见用途是在基于组件的开发中,因为它使一组组件能够以私有方式协作,而不会暴露给应用程序的其余部分代码。例如,用于构建图形用户界面的框架可以提供使用具有内部访问权限的成员进行协作的 Control 和 Form 类。由于这些成员是内部成员,因此它们不会暴露给使用框架的代码。

You can also use the internal modifier along with the InternalsVisibleToassembly level attribute to create "friend" assemblies that are granted special access to the target assembly internal classes.

您还可以使用 internal 修饰符和InternalsVisibleTo程序集级别属性来创建“朋友”程序集,这些程序集被授予对目标程序集内部类的特殊访问权限。

This can be useful for creation of unit testing assemblies that are then allowed to call internal members of the assembly to be tested. Of course no other assemblies are granted this level of access, so when you release your system, encapsulation is maintained.

这对于创建单元测试程序集很有用,然后允许调用要测试的程序集的内部成员。当然,没有其他程序集被授予此级别的访问权限,因此当您发布系统时,会保持封装。

回答by yfeldblum

When you have classes or methods which don't fit cleanly into the Object-Oriented Paradigm, which do dangerous stuff, which need to be called from other classes and methods under your control, and which you don't want to let anyone else use.

当您的类或方法不完全符合面向对象范式时,它们会做危险的事情,需要从您控制的其他类和方法中调用,并且您不想让其他人使用它们.

public class DangerousClass {
    public void SafeMethod() { }
    internal void UpdateGlobalStateInSomeBizarreWay() { }
}

回答by Aaron Powell

When you have methods, classes, etc which need to be accessible within the scope of the current assembly and never outside it.

当你有方法、类等需要在当前程序集的范围内访问时,永远不会超出它。

For example, a DAL may have an ORM but the objects should not be exposed to the business layer all interaction should be done through static methods and passing in the required paramters.

例如,一个 DAL 可能有一个 ORM,但对象不应该暴露给业务层,所有交互都应该通过静态方法并传入所需的参数来完成。

回答by mattlant

I find internal to be far overused. you really should not be exposing certain functionailty only to certain classes that you would not to other consumers.

我发现内部被过度使用了。你真的不应该只向某些类公开某些功能,而你不会向其他消费者公开。

This in my opinion breaks the interface, breaks the abstraction. This is not to say it should never be used, but a better solution is to refactor to a different class or to be used in a different way if possible. However, this may not be always possible.

在我看来,这打破了界面,打破了抽象。这并不是说它不应该被使用,而是更好的解决方案是重构为不同的类,或者如果可能的话以不同的方式使用。然而,这可能并不总是可能的。

The reasons it can cause issues is that another developer may be charged with building another class in the same assembly that yours is. Having internals lessens the clarity of the abstraction, and can cause problems if being misused. It would be the same issue as if you made it public. The other class that is being built by the other developer is still a consumer, just like any external class. Class abstraction and encapsulation isnt just for protection for/from external classes, but for any and all classes.

它可能导致问题的原因是另一个开发人员可能负责在您所在的程序集中构建另一个类。拥有内部结构会降低抽象的清晰度,并且如果被滥用可能会导致问题。如果您将其公开,这将是相同的问题。其他开发人员正在构建的另一个类仍然是消费者,就像任何外部类一样。类抽象和封装不仅仅是为了保护/免受外部类,而是为了任何和所有类。

Another problem is that a lot of developers will thinkthey may need to use it elsewhere in the assembly and mark it as internal anyways, even though they dont need it at the time. Another developer then may think its there for the taking. Typically you want to mark private until you have a definative need.

另一个问题是,许多开发人员会认为他们可能需要在程序集中的其他地方使用它并将其标记为内部,即使他们当时并不需要它。另一个开发人员可能会认为它是可以接受的。通常,您希望在有明确需求之前将其标记为私有。

But some of this can be subjective, and I am not saying it should never be used. Just use when needed.

但其中一些可能是主观的,我并不是说它不应该被使用。只在需要时使用。

回答by Steven A. Lowe

the only thing i have ever used the internal keyword on is the license-checking code in my product ;-)

我唯一使用过的 internal 关键字是我产品中的许可证检查代码;-)

回答by Andrew Kennan

One use of the internal keyword is to limit access to concrete implementations from the user of your assembly.

internal 关键字的一种用途是限制程序集用户对具体实现的访问。

If you have a factory or some other central location for constructing objects the user of your assembly need only deal with the public interface or abstract base class.

如果您有一个工厂或其他一些用于构造对象的中心位置,则程序集的用户只需要处理公共接口或抽象基类。

Also, internal constructors allow you to control where and when an otherwise public class is instantiated.

此外,内部构造函数允许您控制实例化公共类的位置和时间。

回答by Ilya Komakhin

Being driven by "use as strict modifier as you can" rule I use internal everywhere I need to access, say, method from another class until I explicitly need to access it from another assembly.

受“尽可能使用严​​格修饰符”规则的驱动,我在需要访问的任何地方使用内部,例如,来自另一个类的方法,直到我明确需要从另一个程序集访问它。

As assembly interface is usually more narrow than sum of its classes interfaces, there are quite many places I use it.

由于汇编接口通常比其类接口的总和更窄,因此我在很多地方使用它。

回答by Michael Damatov

As rule-of-thumb there are two kinds of members:

作为经验法则,有两种成员:

  • public surface: visible from an external assembly (public, protected, and internal protected): caller is not trusted, so parameter validation, method documentation, etc. is needed.
  • private surface: not visible from an external assembly (private and internal, or internal classes): caller is generally trusted, so parameter validation, method documentation, etc. may be omitted.
  • 公共表面:从外部程序集可见(公共、受保护和内部受保护):调用者不受信任,因此需要参数验证、方法文档等。
  • 私有表面:从外部程序集(私有和内部,或内部类)不可见:调用者通常是可信的,因此可以省略参数验证、方法文档等。

回答by Quibblesome

Noise reduction, the less types you expose the more simple your library is. Tamper proofing / Security is another (although Reflection can win against it).

降噪,你暴露的类型越少,你的库就越简单。防篡改/安全性是另一个(尽管反射可以战胜它)。

回答by cfeduke

A very interesting use of internal - with internal member of course being limited only to the assembly in which it is declared - is getting "friend" functionality to some degree out of it. A friend member is something that is visible only to certain other assemblies outside of the assembly in which its declared. C# has no built in support for friend, however the CLR does.

内部的一个非常有趣的用途——内部成员当然仅限于声明它的程序集——在某种程度上获得了“朋友”功能。朋友成员是仅对声明它的程序集之外的某些其他程序集可见的东西。C# 没有对朋友的内置支持,但是 CLR 有。

You can use InternalsVisibleToAttributeto declare a friend assembly, and all references from within the friend assembly will treat the internal members of your declaring assembly as public within the scope of the friend assembly. A problem with this is that all internal members are visible; you cannot pick and choose.

您可以使用InternalsVisibleToAttribute来声明友元程序集,来自友元程序集内的所有引用都会将声明程序集的内部成员视为友元程序集范围内的公共成员。这样做的一个问题是所有内部成员都是可见的;你不能挑剔。

A good use for InternalsVisibleTo is to expose various internal members to a unit test assembly thus eliminating the needs for complex reflection work arounds to test those members. All internal members being visible isn't so much of a problem, however taking this approach does muck up your class interfaces pretty heavily and can potentially ruin encapsulation within the declaring assembly.

InternalsVisibleTo 的一个很好的用途是将各种内部成员暴露给单元测试程序集,从而消除对复杂反射工作的需要来测试这些成员。所有内部成员都可见并不是什么大问题,但是采用这种方法确实会严重破坏您的类接口,并且可能会破坏声明程序集中的封装。