'protected'And 'protected inside '?

有人能解释一下c#中protectedprotected internal修饰符的区别吗?看起来它们的行为是一样的。

169893 次浏览

"protected internal"访问修饰符是"protected"和"internal"修饰符的联盟

MSDN, Access Modifiers (c# Programming Guide):

protected:

类型或成员只能被相同类或中的代码访问

. Struct,或在该类派生的类中

internal:

类型或成员可以被同一程序集中的任何代码访问, 但不是来自另一个程序集

保护内部:

中程序集中的任何代码都可以访问类型或成员 它被声明,从派生类在另一个 组装。来自另一个程序集的访问必须在类中进行 派生自受保护对象所在类的 内部元素被声明,它必须通过 派生类类型的实例

请注意,: protected internal表示“protected OR internal”(同一程序集中的任何类,或任何派生类-即使它在不同的程序集中)。

...为了完整起见:

private:

类型或成员只能被相同类或中的代码访问 struct。< / p >

public:

类型或成员可以被相同类型中的任何其他代码访问

.程序集或引用它的另一个程序集

private protected:

类派生的包含类或类型的访问被限制为 包含当前程序集中的类 (c# 7.2以来可用) < / p >

protected可以被任何程序集的任何子类使用。

protected internalprotected的所有内容,加上同一程序集中的任何内容都可以访问它。

重要的是,它并不意味着“同一程序集中的子类”——它是两者的并集,而不是交集。

在实践中,关于方法:

受保护的 -继承类可访问,否则为私有。

内部 -只对程序集中的类是公共的,否则是私有的。

保护内部 -表示受保护的内部-方法可以被程序集内的任何类的继承类而且访问。

受保护的:变量或方法只对子类可用(在任何程序集中)

保护内部:可用于任何程序集中的子类。而且可用于同一程序集中的所有类

公共 -成员(函数&变量)声明为公共的,可以从任何地方访问。

私人 -私有成员不能从类外部访问。这是成员的默认访问说明符,即如果你没有为成员(变量或函数)指定访问说明符,它将被认为是私有的。因此,string PhoneNumber;相当于私有字符串PhoneNumber。

受保护的 - Protected成员只能从子类中访问。

内部 -它只能在同一个程序集中访问。

保护内部 -它可以在同一个程序集中访问,也可以在派生类中访问。

我已经把这些术语的定义读得很清楚了。

Protected:访问限制在类定义内以及从该类继承的任何类内。类型或成员只能通过同一类或结构中的代码或从该类派生的类中的代码访问。

内部:访问仅限于当前项目程序集中定义的类。类型或成员只能由同一类中的代码访问。

Protected-Internal:访问权限仅限于从包含类派生的当前程序集或类型。

保护成员

类的受保护成员仅在包含类中可用(在其中声明了类),并且在程序集内部和程序集外部的派生类中可用。

表示驻留在程序集外部的类仅通过继承该类来使用其他程序集的受保护成员。

可以通过继承该类在程序集外部公开Protected成员,并仅在派生类中使用它。

注意:不能使用派生类中的对象访问受保护的成员。

内部成员

类的内部成员是可用的,或在程序集中创建对象或在派生类中访问,或者您可以说可以在程序集中的所有类中访问它。

注意:内部成员不能在程序集外部使用对象创建或在派生类中访问。

保护内部

Protected内部访问修饰符为Protected或Internal的组合。

受保护内部成员可以在其声明创建对象或通过继承该类的整个程序集中使用。并且只能在派生类的程序集之外访问。

注意:受保护的内部成员在同一程序集内作为内部成员工作,在程序集外作为受保护成员工作。

在理解“受保护的内部”访问器的作用域方面仍然存在很多困惑,尽管大多数人都正确地定义了该定义。这帮助我理解了“受保护的”和“受保护的内部”之间的混淆:

公共在程序集内外都是公共的(公共内部/公共外部)

受保护的实际上是在程序集内外受到保护的(内部保护/外部保护)(在顶级类中不允许)

私人实际上是程序集内部和外部的私有(私人内部/私人外部)(在顶级类中不允许)

内部在程序集内部实际上是公共的,但在程序集外部却像private (公共内部/排除外部)一样被排除在外。

保护内部在程序集内部是公共的,但在程序集外部是受保护的(内部公开/外部受保护) (不允许在顶级类)

正如你所看到的,保护内部是一个非常奇怪的野兽。不直观。

这就引出了一个问题,为什么微软不创建一个(保护内部/排除外部),或者我猜是某种“私有保护”或“内部保护”?哈哈看起来不完整?

更令人困惑的是,您可以在受保护的、内部的或私有类型中嵌套公共或受保护的内部嵌套成员。为什么要访问排除外部程序集访问的内部类中的嵌套“受保护内部”?

微软表示,这样的嵌套类型受到其父类型作用域的限制,但编译器并不是这么说的。您可以在内部类中编译受保护的内部程序,这应该将范围限制为程序集。

对我来说,这是一个不完整的设计。它们应该简化所有类型的范围,使系统清楚地考虑到继承,以及嵌套类型的安全性和层次结构。这将使对象的共享非常直观和细粒度,而不是基于不完整的作用域系统发现类型和成员的可访问性。

受保护的内部最佳套件,当您希望在来自另一个程序集中的派生类中使用成员或类型,同时只想在父程序集中使用该成员或类型,而不从声明它的类派生时。 此外,如果您只想使用一个成员或类型而不从另一个类派生,则在同一个程序集中只能使用internal

下表显示了其中的差异。protected internalprotected相同,除了它也允许来自同一程序集中的其他类的访问。

 c#修饰符的比较

protected internal想象成在同一个字段、属性或方法上应用两个访问修饰符(protectedinternal)。

在现实世界中,想象一下我们为人们提供参观博物馆的特权:

  1. 解析:句意:每个人都可以参观博物馆(内部)。
  2. 他们父母居住的城市的每个人都被允许参观博物馆。

我们可以这样把它们放在一起:

每个人都可以参观这座城市(内部),每个人都可以参观他们父母居住的城市(受保护)。

编程世界:

内部:该字段在程序集(项目)中的任何地方都可用。这就像说它在它的项目范围内是public(但不能在项目范围之外访问,即使是那些继承自该类的程序集之外的类)。类型的每个实例都可以在该程序集(项目范围)中看到它。

受保护的:仅仅意味着所有派生类都可以看到它(在程序集内部或外部)。例如,派生类可以使用:base.NameOfProtectedInternal查看其方法和构造函数中的字段或方法。

因此,将这两个访问修饰符放在一起(protected internal),你在项目中就有了可以是公共的东西,并且可以被那些在它们的作用域内从该类继承的对象看到。

它们可以写在internal protected中,而改变了含义,但写在protected internal中更方便。

这个描述可能会有帮助

Internal Member

Internal class的成员可用或在assembly创建对象或派生的class中访问,或者你可以说它可以在assembly中的所有classes中访问。

Protected Member

Protected class的成员只能在包含的class中(在其中声明了它)以及在assembly内部和assembly之外的派生class中可用。

Protected Internal

Protected Internal访问修饰符是组合ProtectedInternal

Protected Internal成员可以在整个assembly中可用,其中它声明创建object或继承class。并且只能在派生的class中在assembly之外访问。