(C# 7.2) "private protected"修饰符的用例是什么?



C# 7.2 引入了私有受保护的修饰符。

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

我试图理解为什么 C# 语言团队添加了此功能。在谷歌上进行了广泛的搜索,并阅读和观看了"最新消息"媒体(我看了Mads Torgerson的新闻稿,细节和视频)之后,我仍然没有更明智。

对我来说,这似乎允许开发人员打破 Liskov 替换原则,但这可能是因为我不明白为什么现在存在此功能。

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

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

private protected实际上意味着受保护和内部。也就是说 - 成员只能对同一程序集中的子类访问,而不能对程序集外部的子类访问(因此"受保护"所暗示的限制被缩小 - 变得更加严格)。如果在程序集中生成类的层次结构,并且不希望其他程序集中的任何子类访问该层次结构的某些部分,则此功能非常有用。

我们可以举乔恩·斯基特(Jon Skeet)在评论中提供的例子。假设你有类

public class MyClass {
}

并且您希望只能在当前程序集中继承它,但不希望允许直接实例化此类,除非从此类层次结构中。

仅在当前程序集内继承可以使用内部构造函数实现

public class MyClass {
internal MyClass() {
}
}

防止直接实例化,除了当前类层次结构之外,可以使用受保护的构造函数来实现:

public class MyClass {
protected MyClass() {
}
}

要获得两者 - 您需要private protected构造函数:

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

对于两个单词的访问修饰符,我有这个概念 - 第一个访问器与另一个程序集相关,第二个访问器与定义它的程序集相关。

受保护的内部

  • 在另一个程序集中受保护:只能在子类中访问。

  • 当前程序集中的
  • 内部:当前程序集中的每个人都可以访问。

私人保护

  • 另一个程序集中的私有:不可访问。
  • 在当前程序集中受保护:只能在子类中访问。

假设您有一个名为SomeHelper的内部类,您希望将其用作公共抽象基类实现的一部分:

public abstract class Test
{
// Won't compile because SomeHelper is internal.
protected SomeHelper CreateHelper()
{
return new SomeHelper();
}
public int Func(int x)
{
var helper = CreateHelper();
return helper.DoSomething(x);
}
}
internal class SomeHelper
{
public virtual int DoSomething(int x)
{
return -x;
}
}

这不会编译,因为不能让受保护的方法返回内部类型。您唯一的办法是不要以这种方式使用SomeHelper,或者公开SomeHelper

(你可以SomeHelper一个受保护的Test内部类,但如果SomeHelper旨在供其他不是从基类派生的类使用,这是行不通的。

引入private protected功能后,您可以像这样声明CreateHelper()

private protected SomeHelper CreateHelper()
{
return new SomeHelper();
}

现在它将编译,您不必公开您的内部结构。

受保护的内部意味着"受保护或内部" - 在以下情况下,都可以访问使用此访问修饰符定义的任何类型/成员 - (A) 在同一程序集中, (B) 在另一个程序集中定义并派生自容器类的类

私有保护意味着"受保护和内部" - 在以下方案中可以访问使用此访问修饰符定义的任何类型/成员 - 继承自容器类并属于同一程序集的类

最新更新