protected
有人可以解释一下 C# 中的和protected internal
修饰符之间的区别吗?看起来他们的行为是相同的。
11 回答
“protected internal”访问修饰符是“protected”和“internal”修饰符的联合。
受保护:
类型或成员只能由同一类或结构中的代码或从该类派生的类中的代码访问。
内部:
类型或成员可以由同一程序集中的任何代码访问,但不能从另一个程序集中访问。
受保护的内部:
类型或成员可以被声明它的程序集中的任何代码访问,或者从另一个程序集中的派生类中访问。来自另一个程序集的访问必须在派生自声明受保护内部元素的类的类声明中进行,并且必须通过派生类类型的实例进行。
请注意:protected internal
表示“protected
或internal
”(同一程序集中的任何类,或任何派生类 - 即使它在不同的程序集中)。
...为了完整性:
私人:
类型或成员只能由同一类或结构中的代码访问。
公开:
类型或成员可以由同一程序集或引用它的另一个程序集中的任何其他代码访问。
私人保护:
访问仅限于从当前程序集中的包含类派生的包含类或类型。
(自 C# 7.2 起可用)
protected
可以被任何程序集的任何子类使用。
protected internal
是所有的东西protected
,加上同一个程序集中的任何东西都可以访问它。
重要的是,它并不意味着“同一个程序集中的子类”——它是两者的结合,而不是交集。
在实践中,关于方法:
protected - 可被继承的类访问,否则是私有的。
internal - 仅对程序集内的类公开,否则为私有。
protected internal - 意味着 protected或internal - 方法可以被继承的类和程序集中的任何类访问。
在理解“受保护的内部”访问器的范围方面仍然存在很多混淆,尽管大多数访问器的定义都正确定义。这有助于我理解“受保护”和“受保护内部”之间的混淆:
public是真正的公共内部和外部的程序集(公共内部/公共外部)
protected在程序集内部和外部确实受到保护(受保护的内部/受保护的外部)(不允许在顶级类中使用)
private在程序集内部和外部确实是私有的(私有内部/私有外部)(不允许在顶级课程中使用)
internal在程序集内确实是公共的,但在程序集之外被排除在私有(公共内部/排除外部)之外
protected internal在程序集内部确实是公共的,但在程序集外部是受保护的(公共内部/受保护外部)(不允许在顶级类中使用)
如您所见,受保护的内部是一种非常奇怪的野兽。不直观。
现在引出了一个问题,为什么微软没有创建(受保护的内部/排除外部),或者我猜是某种“私人保护”或“内部保护”?哈哈。似乎不完整?
更令人困惑的是,您可以将公共或受保护的内部嵌套成员嵌套在受保护、内部或私有类型中。为什么要在排除外部程序集访问的内部类中访问嵌套的“受保护的内部”?
微软表示这种嵌套类型受其父类型范围的限制,但这不是编译器所说的。您可以在内部类中编译受保护的内部,这应该将范围限制在程序集中。
对我来说,这感觉像是不完整的设计。它们应该将所有类型的范围简化为一个明确考虑继承以及嵌套类型的安全性和层次结构的系统。这将使对象的共享变得非常直观和精细,而不是基于不完整的范围系统发现类型和成员的可访问性。
protected:变量或方法仅对子类可用(在任何程序集中)
protected internal:可用于任何程序集中的子类以及同一程序集中的所有类
我已经为这些术语读出了非常清晰的定义。
受保护:访问仅限于类定义和从该类继承的任何类。类型或成员只能由同一类或结构中的代码或从该类派生的类中的代码访问。
内部:访问仅限于当前项目程序集中定义的类。类型或成员只能由同一类中的代码访问。
Protected-Internal:访问仅限于当前程序集或从包含类派生的类型。
public - 声明为 public 的成员(函数和变量)可以从任何地方访问。
private - 不能从类外部访问私有成员。这是成员的默认访问说明符,即如果您没有为成员(变量或函数)指定访问说明符,它将被视为私有的。因此,字符串电话号码;相当于私有字符串PhoneNumber。
protected - 受保护的成员只能从子类访问。
internal - 它只能在同一个程序集中访问。
protected internal - 它可以在同一个程序集中以及在派生类中访问。
受保护成员
类的受保护成员仅在包含的类(已在其中声明)以及程序集内和程序集外的派生类中可用。
表示如果一个位于程序集外部的类只能通过继承该类来使用另一个程序集的受保护成员。
我们可以通过继承该类将受保护的成员暴露在程序集之外,并仅在派生类中使用它。
注意:使用派生类中的对象无法访问受保护的成员。
内部成员
类的内部成员在程序集中是可用的,或者可以在程序集中创建对象或在派生类中访问,或者您可以说它可以在程序集中的所有类中访问。
注意:使用对象创建或在派生类中无法在程序集外部访问内部成员。
受保护的内部
Protected Internal 访问修饰符是 Protected 或 Internal 的组合。
受保护的内部成员可以在它声明创建对象或继承该类的整个程序集中可用。并且只能在派生类中的程序集外部访问。
注意:受保护的内部成员在同一程序集中作为内部成员工作,在程序集外部作为受保护成员工作。
当您希望在来自另一个程序集的派生类中使用成员或类型同时只想使用父程序集中的成员或类型而不从声明它的类派生时,受保护的内部最佳套件。此外,如果您只想使用成员或类型而不从另一个类派生,则在同一个程序集中您只能使用内部。
可以想象在同一个字段、属性或方法上protected internal
应用两个访问修饰符(protected
和)。internal
在现实世界中,假设我们正在为人们颁发参观博物馆的特权:
- 城市内的每个人都可以参观博物馆(内部)。
- 父母住在这里的城市以外的每个人都可以参观博物馆(受保护)。
我们可以通过以下方式将它们组合在一起:
允许市内(内部)和父母住在这里的市外(受保护)的每个人参观博物馆(受保护的内部)。
编程世界:
internal:该字段在程序集(项目)中的任何地方都可用。这就像说它public
在其项目范围内(但即使是从该类继承的程序集之外的那些类也不能在项目范围之外访问)。该类型的每个实例都可以在该程序集(项目范围)中看到它。
protected:仅仅意味着所有派生类都可以看到它(在程序集内部或外部)。例如,派生类可以使用以下方法查看其方法和构造函数中的字段或方法:base.NameOfProtectedInternal
。
因此,将这两个访问修饰符放在一起(protected internal
),您就有了可以在项目中公开的内容,并且可以被那些在其范围内从该类继承的人看到。
它们可以写在 中
internal protected
,而且不改变意思,但写起来很方便protected internal
。