“受保护的”和“受保护的内部”有什么区别?


244

有人可以详细说明一下C#中“受保护的”和“受保护的内部”修饰符之间的区别吗?看起来它们的行为方式相同。

Answers:


402

“受保护的内部”访问修饰符是联盟双方的“保护”和“内部”修饰符。

MSDN,访问修饰符(C#编程指南)

受保护的

类型或成员只能由相同类或结构中的代码或从该类派生的类中的代码访问。

内部

可以通过同一程序集中的任何代码访问类型或成员,但不能从另一个程序集中访问。

受保护的内部

可以在声明了该类型或成员的程序集中的任何代码访问该类型或成员,或者从另一个程序集中的派生类中访问该类型或成员。来自另一个程序集的访问必须在从声明受保护内部元素的类派生的类声明内进行,并且必须通过派生类类型的实例进行。

注意:的protected internal意思是“ protectedOR internal”(同一程序集中的任何类,或任何派生类-即使在不同的程序集中)。

...为了完整性:

私人的

类型或成员只能由相同类或结构中的代码访问。

公开

该类型或成员可以由同一程序集或引用它的另一个程序集中的任何其他代码访问。

受私人保护

访问仅限于当前程序集中包含类或从包含类派生的类型。
自C#7.2起可用


2
我可以拥有一个成员,protected internal以便它protected处于当前装配状态,并且在外部完全不可用吗?
Shimmy Weitzhandler,2015年

8
那将是“受保护的”,不是吗?
CAD猛击

2
@Shimmy:您可以使用带有受保护方法的内部。但是,整个类将无法从外部程序集中获得。
M4N

1

@Shimmy至少CLR确实支持受保护和内部可访问性交集的概念,但是C#语言不支持。C#仅支持两个访问修饰符的并集。
RBT

89

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

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

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


3
仅供读者参考,CLR也支持受保护和内部可访问性交集的概念,但是C#不支持。C#仅支持本文所述的两者的并集。
RBT

1
只是供读者阅读的FYI,可以使用private protectedC#7.2中引入的access修饰符实现“同一程序集中的子类”
LordWilmore,

52

-更新答案2019年-

您可以在下表中找到基于差异的可访问性,是,

在此处输入图片说明


4
漂亮的答案,它非常清楚地传达了每个访问修饰符之间的差异。
e_i_pi

23

在实践中,关于方法:

protected-继承的类可访问,否则为私有。

内部 -仅对程序集中的类公开,否则为私有。

protected internal-表示受保护的方法内部方法-对于继承的类和程序集中的任何类都可以访问。


1
我会用OR来表达这一点,因为要么两者都不是必须的。
布赖恩·拉斯穆森

我不完全同意“受保护的”描述中的“用于更改基类行为”部分。我想说的是在这里使用“虚拟”(在基类上)和“覆盖”(在派生类上)。
M4N

有没有办法将成员标记为protectedAND internal
Shimmy Weitzhandler,2015年

@Shimmy:是的protected internal
abatishchev

1
@Shimmy两年后,是的。现在在C#7.2中有一种方法。其所谓的private protected docs.microsoft.com/en-us/dotnet/csharp/language-reference/...
圣保利Østerø

10

尽管大多数人正确定义了定义,但在理解“受保护的内部”访问器的范围时仍然有很多困惑。这有助于我理解“受保护的”和“受保护的内部”之间的混淆:

public实际上是程序集内部和外部的公共public内部/ public external

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

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

内部在装配内部确实是公共的,但是像私有的那样在装配外部被排除(公共内部/外部外部

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

如您所见,受保护的内部是一个非常奇怪的野兽。不直观。

现在,提出了一个问题,为什么Microsoft不创建(受保护的内部/受排除的外部),或者我猜某种“私有保护”或“内部保护”?大声笑。似乎不完整?

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

微软表示,此类嵌套类型受其父类型范围的限制,但这不是编译器所说的。您可以在内部类中编译受保护的内部,这将范围限制为仅程序集。

对我来说,这感觉就像是不完整的设计。它们应简化系统的所有类型的范围,使其清楚地考虑继承,还应考虑嵌套类型的安全性和层次结构。这将使对象的共享极为直观和精细,而不是基于不完整的作用域系统发现类型和成员的可访问性。


1
私有保护现已添加到C#7.2中,该代码基本上是内部AND保护的。
PauliØsterø17年

7

protected:变量或方法仅对子类可用(在任何程序集中)

受保护的内部:可用于任何程序集中的子类以及同一程序集中的所有类


3

我已经为这些术语读出了非常明确的定义。

受保护的:访问仅限于类定义以及从该类继承的任何类之内。该类型或成员只能由相同类或结构或从该类派生的类中的代码访问。

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

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


1

受保护的成员

类的受保护成员只能在所包含的类(在其中声明了该类)中以及在程序集中以及在程序集外部的派生类中使用。

表示驻留在程序集外部的类是否只能通过继承该类来使用另一个程序集的受保护成员。

我们可以通过继承该类并在派生类中使用它来在程序集外部公开受保护的成员。

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

内部成员

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

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

受保护的内部

受保护的内部访问修饰符是受保护的或内部的组合。

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

注意:“受保护的内部”成员在同一装配中用作“内部”,而对于在装配外部的“内部”则用作“受保护”。


1

上市 -成员(功能与变量)声明为public可以从任何地方访问。

私人 -私人成员不能从班级外部访问。这是成员的默认访问说明,即,如果您未为成员(变量或函数)指定访问说明,它将被视为私有。因此,字符串PhoneNumber; 等效于私有字符串PhoneNumber。

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

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

受保护的内部 -可以在同一程序集中以及派生类中对其进行访问。


0

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.