C# 7.2 introduces the private protected modifier

我一直保护对具有属性的字段的访问,允许通过Get/Set方法进行访问,因为我通常不希望对象的内部状态被我自己的类以外的任何东西修改.

我试图理解为什么C语言团队添加了这个功能.在谷歌上进行了广泛的搜索,阅读并观看了"新事物"媒体(我已经观看了press releasedetailsvideo by Mads Torgerson),我仍然没有变得更聪明.

在我看来,这似乎允许开发人员打破Liskov替换原则,但这可能是因为我不明白为什么现在存在这个特性.

我理解它是如何使用的,只是不理解为什么——请有人提供一个真实世界的使用示例,而不是MSDN文档中的人为示例?

推荐答案

在C#7.2之前,我们有protected internal个修饰语.这实际上意味着受保护的或内部的,也就是说,子类和当前程序集中的任何类都可以访问成员A,即使该类不是类A的子类(因此"受保护"所隐含的限制被放宽).

private protected真的意味着受保护的和内部的.也就是说,成员只对同一程序集中的子类可访问,而对程序集外部的子类不可访问(因此"受保护"所暗示的限制被缩小了-变得更加严格).如果您在程序集中构建类的层次 struct ,且不希望其他程序集中的任何子类访问该层次 struct 的某些部分,这将非常有用.

我们可以举Jon Skeet提供in comments的例子.假设你有课

public class MyClass {

}

您希望仅在当前程序集中从它继承,但不希望允许直接实例化这个类,除非是从这个类层次 struct 中.

只能通过内部构造函数在当前程序集中实现继承

public class MyClass {
    internal MyClass() {
    }
}

使用受保护的构造函数可以防止直接实例化,除非使用当前类层次 struct :

public class MyClass {
    protected MyClass() {
    }
}

要实现这两个目标,你需要private protected个构造器:

public class MyClass {
    private protected MyClass() {
    }
}

.net相关问答推荐

DotNet COM初始化问题

AppShell - 返回导航失败,匹配的路由不明确......但我只注册了一次路由

为什么我在环境变量中有不同的值?

代理、包装器或外观类之间有什么区别

Style 和 ControlTemplate 的区别

读取方法的属性值

数据库架构更改后更新 LINQ to SQL 类的最佳方法

在 JavaScript 中使用 String.Format?

Convert.ToBoolean 和 Boolean.Parse 不接受 0 和 1

为什么 System.Timers.Timer 能在 GC 中存活,而 System.Threading.Timer 不能?

.NET 中是否有可序列化的通用键/值对类?

Dapper 是否支持 SQL 2008 表值参数?

X509Certificate 构造函数异常

监听依赖属性的变化

一个接口是否应该继承另一个接口

静态方法继承的正确替代方法是什么?

让 String.Replace 只打整个单词的方法

如何比较泛型类型的值?

Windows 服务在哪个目录中运行?

序列化和反序列化 .NET 对象的最快方法