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

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


当前回答

前几天,也许是一个星期,在一个我不记得的博客上看到了一个有趣的东西。基本上这不是我的功劳,但我认为它可能有一些有用的应用。

假设您想让另一个程序集看到一个抽象类,但不希望有人能够继承它。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();
    }
  }
}

如您所见,它有效地允许某人使用父类而不能够继承。

其他回答

唯一一件事我曾经使用内部关键字是许可证检查代码在我的产品;-)

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

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

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.

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

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

我有一个项目,使用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)无法直接访问数据模型,从而确保业务层始终充当中介。

这是我第一次真正使用内部,它被证明是非常有用的。

请记住,当有人查看您的项目名称空间时,任何定义为public的类都会自动显示在智能感知中。从API的角度来看,只向项目的用户展示他们可以使用的类是很重要的。使用internal关键字隐藏他们不应该看到的东西。

如果项目A的Big_Important_Class打算在项目外部使用,那么不应该将其标记为内部。

然而,在许多项目中,经常会有一些实际上只打算在项目中使用的类。例如,您可能拥有一个类,该类保存参数化线程调用的参数。在这些情况下,您应该将它们标记为内部的,如果没有其他原因,只是为了保护自己不受意外的API更改的影响。

内部类使您能够限制程序集的API。这有很多好处,比如让你的API更容易理解。

此外,如果程序集中存在错误,修复程序引入破坏性更改的可能性就会降低。如果没有内部类,您将不得不假设更改任何类的公共成员都将是破坏性的更改。对于内部类,您可以假设修改它们的公共成员只会破坏程序集的内部API(以及InternalsVisibleTo属性中引用的任何程序集)。

我喜欢在类级和程序集级进行封装。有一些人不同意这一点,但很高兴知道功能是可用的。