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

我知道内部修饰符限制了对当前程序集的访问,但何时以及在何种情况下应该使用它?


当前回答

这个怎么样:通常建议不要向程序集的外部用户公开List对象,而是公开IEnumerable对象。但是在程序集中使用List对象要容易得多,因为您可以获得数组语法和所有其他List方法。因此,我通常有一个内部属性,公开要在程序集中使用的List。

欢迎对这种方法提出意见。

其他回答

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

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

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

来自MSDN(通过archive.org):

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

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

这对于创建单元测试程序集非常有用,然后允许这些程序集调用要测试的程序集的内部成员。当然,没有其他程序集被授予这种级别的访问权限,所以当您发布系统时,将维护封装。

如果您正在编写一个DLL,它将大量复杂的功能封装到一个简单的公共API中,那么“internal”将用于不公开的类成员。

隐藏复杂性(又称封装)是高质量软件工程的主要概念。

这个例子包含两个文件:Assembly1.cs和Assembly2.cs。第一个文件包含一个内部基类BaseClass。在第二个文件中,尝试实例化BaseClass将产生一个错误。

// Assembly1.cs
// compile with: /target:library
internal class BaseClass 
{
   public static int intM = 0;
}

// Assembly1_a.cs
// compile with: /reference:Assembly1.dll
class TestAccess 
{
   static void Main()
   {  
      BaseClass myBase = new BaseClass();   // CS0122
   }
}

在本例中,使用示例1中使用的相同文件,并将BaseClass的可访问性级别更改为public。还要将成员IntM的可访问性级别更改为internal。在这种情况下,可以实例化类,但不能访问内部成员。

// Assembly2.cs
// compile with: /target:library
public class BaseClass 
{
   internal static int intM = 0;
}

// Assembly2_a.cs
// compile with: /reference:Assembly1.dll
public class TestAccess 
{
   static void Main() 
   {      
      BaseClass myBase = new BaseClass();   // Ok.
      BaseClass.intM = 444;    // CS0117
   }
}

来源:http://msdn.microsoft.com/en-us/library/7c5ka91b (VS.80) . aspx

其思想是,当您设计一个库时,只有打算从外部(由库的客户端)使用的类应该是公共的。这样你就可以隐藏

可能在未来的版本中更改(如果它们是公开的,您将破坏客户端代码) 对客户是无用的,可能会造成混乱 不安全(所以使用不当会严重破坏你的库)

etc.

如果你在开发内部解决方案,那么使用内部元素就不是那么重要了,因为通常客户会经常与你联系,并且/或访问代码。不过,它们对库开发人员来说相当重要。