有人能解释一下c#中受保护的内部修饰符和受保护的内部修饰符的区别吗?看起来它们的行为是一样的。
当前回答
public——声明为public的成员(函数和变量)可以从任何地方访问。
private -私有成员不能从类外部访问。这是成员的默认访问说明符,即如果你没有为成员(变量或函数)指定访问说明符,它将被认为是私有的。因此,string PhoneNumber;相当于私有字符串PhoneNumber。
protected -受保护的成员只能从子类访问。
internal -只能在同一个程序集中访问它。
protected internal -它可以在同一个程序集中访问,也可以在派生类中访问。
其他回答
“protected internal”访问修饰符是“protected”和“internal”修饰符的联合。
来自MSDN, Access Modifiers (c# Programming Guide):
保护:
类型或成员只能由相同类或类中的代码访问 结构,或者在从该类派生的类中。
内部:
类型或成员可以被同一程序集中的任何代码访问, 但不是来自另一个集会。
保护内部:
中的程序集中的任何代码都可以访问类型或成员 它是在哪个类中声明的,还是在另一个类中的派生类中 组装。来自另一个程序集的访问必须在类中进行 派生自受保护对象所在类的 内部元素被声明,它必须通过 派生类类型的实例。
注意:protected internal意味着“protected OR internal”(同一程序集中的任何类,或任何派生类——即使它在不同的程序集中)。
...为了完整起见:
私人:
类型或成员只能由相同类或类中的代码访问 结构体。
公众:
类型或成员可以被相同类型中的任何其他代码访问 程序集或引用该程序集的其他程序集。
私人保护:
类派生的包含类或类型的访问受到限制 在当前程序集中包含类。 (自c# 7.2起可用)
下表显示了其中的差异。Protected internal与Protected相同,只是它还允许来自同一程序集中其他类的访问。
这个描述可能会有帮助
内部成员
类的内部成员是可用的,或在程序集中创建对象或在派生类中访问,或者您可以说可以在程序集中的所有类中访问它。
保护成员
类的受保护成员仅在包含类中可用(在其中声明了类),并且在程序集内部和程序集外部的派生类中可用。
保护内部
Protected内部访问修饰符为Protected或Internal的组合。
受保护内部成员可以在其声明创建对象或通过继承该类的整个程序集中使用。并且只能在派生类的程序集之外访问。
Protected可以被任何程序集的任何子类使用。
Protected internal是指受保护的所有内容,再加上同一程序集中的任何内容都可以访问它。
重要的是,它并不意味着“同一程序集中的子类”——它是两者的并集,而不是交集。
在理解“受保护的内部”访问器的作用域方面仍然存在很多困惑,尽管大多数人都正确地定义了该定义。这帮助我理解了“受保护的”和“受保护的内部”之间的混淆:
Public在集合内部和外部都是公共的(Public internal / Public external)
Protected实际上是在程序集内部和外部受到保护(Protected internal / Protected external)(不允许在顶级类上)
Private在程序集内部和外部都是私有的(Private internal / Private external)(不允许在顶级类上)
Internal在集合内部是公共的但在集合外部是不存在的比如private (public Internal / excluded external)
Protected internal在程序集内部实际上是公共的,但在程序集外部是受保护的(公共内部/受保护的外部) (不允许在顶级类)
如你所见,受保护的内部是一个非常奇怪的野兽。不直观。
这就引出了一个问题,为什么微软不创建一个(受保护的内部/排除的外部),或者我猜是某种“私人保护”或“内部保护”?哈哈看起来不完整?
更令人困惑的是,您可以在受保护的、内部的或私有类型中嵌套公共或受保护的内部嵌套成员。为什么要访问排除外部程序集访问的内部类中的嵌套“受保护内部”?
微软表示,这样的嵌套类型受到其父类型作用域的限制,但编译器并不是这么说的。您可以在内部类中编译受保护的内部程序,这应该将范围限制为程序集。
对我来说,这是一个不完整的设计。它们应该简化所有类型的范围,使系统清楚地考虑到继承,以及嵌套类型的安全性和层次结构。这将使对象的共享非常直观和细粒度,而不是基于不完整的作用域系统发现类型和成员的可访问性。
推荐文章
- .NET中的Map和Reduce
- 我如何能使一个组合框不可编辑的。net ?
- .NET反射的成本有多高?
- 实体框架回滚并移除不良迁移
- 将流转换为字符串并返回
- 在c#中检查字符串是否只包含数字的最快方法
- IEquatable和重写Object.Equals()之间的区别是什么?
- 创建一个堆栈大小为默认值50倍的线程有什么危险?
- 转换JSON字符串到JSON对象c#
- 显示两个datetime值之间的小时差值
- 如何设置enum为空
- 选择Enum类型的默认值而无需更改值
- 我如何设置在一个组合框中选择的项目,以匹配我的字符串使用c# ?
- String与StringBuilder
- 如何在ASP中使用ILogger进行单元测试。网络核心