你能解释一下c#中internal关键字的实际用法吗?
我知道内部修饰符限制了对当前程序集的访问,但何时以及在何种情况下应该使用它?
你能解释一下c#中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
其他回答
当您有方法、类等需要在当前程序集范围内访问,而不能在当前程序集范围外访问时。
例如,一个DAL可能有一个ORM,但对象不应该暴露给业务层,所有交互都应该通过静态方法完成,并传递所需的参数。
前几天,也许是一个星期,在一个我不记得的博客上看到了一个有趣的东西。基本上这不是我的功劳,但我认为它可能有一些有用的应用。
假设您想让另一个程序集看到一个抽象类,但不希望有人能够继承它。Sealed不能工作,因为它是抽象的,这个程序集中的其他类确实从它继承。Private将不起作用,因为您可能希望在另一个程序集中声明一个Parent类。
namespace Base.Assembly { public abstract class Parent { internal abstract void SomeMethod(); } //This works just fine since it's in the same assembly. public class ChildWithin : Parent { internal override void SomeMethod() { } } } namespace Another.Assembly { //Kaboom, because you can't override an internal method public class ChildOutside : Parent { } public class Test { //Just fine private Parent _parent; public Test() { //Still fine _parent = new ChildWithin(); } } }
如您所见,它有效地允许某人使用父类而不能够继承。
减少噪音,你暴露的类型越少,你的库就越简单。 防篡改/安全性是另一个问题(尽管Reflection可以战胜它)。
您希望从同一程序集中的许多其他类中访问,但希望确保其他程序集中的代码不能访问的实用程序或帮助程序类/方法。
来自MSDN(通过archive.org):
内部访问的一个常见用途是在基于组件的开发中,因为它允许一组组件以私有的方式进行合作,而不会向其余应用程序代码公开。例如,用于构建图形用户界面的框架可以提供Control和Form类,它们使用具有内部访问权限的成员进行合作。因为这些成员是内部的,所以它们不会暴露给使用框架的代码。
还可以使用内部修饰符和InternalsVisibleTo程序集级别属性来创建“友程序集”,这些程序集被授予对目标程序集内部类的特殊访问权。
这对于创建单元测试程序集非常有用,然后允许这些程序集调用要测试的程序集的内部成员。当然,没有其他程序集被授予这种级别的访问权限,所以当您发布系统时,将维护封装。
我有一个项目,使用LINQ-to-SQL的数据后端。我有两个主要的名称空间:Biz和Data。LINQ数据模型存在于数据中,并标记为“内部”;Biz命名空间拥有围绕LINQ数据类的公共类。
这就是数据。Client和business .Client;后者公开了数据对象的所有相关属性,例如:
private Data.Client _client;
public int Id { get { return _client.Id; } set { _client.Id = value; } }
Biz对象有一个私有构造函数(强制使用工厂方法)和一个内部构造函数,看起来像这样:
internal Client(Data.Client client) {
this._client = client;
}
库中的任何业务类都可以使用它,但是前端(UI)无法直接访问数据模型,从而确保业务层始终充当中介。
这是我第一次真正使用内部,它被证明是非常有用的。