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

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


当前回答

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

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

etc.

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

其他回答

在“使用尽可能严格的修饰符”规则的驱动下,我在需要访问的任何地方都使用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

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

在我看来,这打破了界面,打破了抽象。这并不是说永远不应该使用它,而是更好的解决方案是重构到不同的类,或者在可能的情况下以不同的方式使用。然而,这并不总是可能的。

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.

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

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

在构建非托管代码的包装器时,internal关键字被大量使用。

当你有一个基于C/ c++的库,你想要DllImport,你可以导入这些函数作为一个类的静态函数,并使他们内部,所以你的用户只能访问你的包装器,而不是原始的API,所以它不能乱动任何东西。函数是静态的,您可以在程序集中的任何地方使用它们,用于您需要的多个包装器类。

你可以看看Mono。Cairo,它是使用这种方法的Cairo库的包装器。

当您有方法、类等需要在当前程序集范围内访问,而不能在当前程序集范围外访问时。

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