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

What is the use case for the (C# 7.2) "private protected" modifier?

C# 7.2 introduces the private protected modifier

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

我想了解为什么 C# 语言团队添加了此功能。在 google 上进行了广泛搜索,并阅读和观看了“最新消息”媒体(我看过 press release, details and video by Mads Torgerson)之后,我仍然 none 更聪明。

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

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

在 C# 7.2 之前我们有 protected internal 修饰符。这实际上意味着 protected OR internal,即 - child classes 以及当前程序集中的任何 class 都可以访问成员 A,即使 [=41] =] 不是 class A 的 child(因此 "protected" 隐含的限制放宽了)。

private protected 的真正意思是受保护和内部。也就是说 - 成员只能访问同一程序集中的 child classes,但不能访问程序集外部的 child classes(因此 "protected" 变窄了 - 变得更加严格)。如果您在程序集中构建 classes 的层次结构并且不希望来自其他程序集的任何 child classes 访问该层次结构的某些部分,这将很有用。

我们可以举个例子Jon Skeet provided 。假设你有 class

public class MyClass {

}

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

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

public class MyClass {
    internal MyClass() {
    }
}

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

public class MyClass {
    protected MyClass() {
    }
}

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

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

假设您有一个名为 SomeHelper 的内部 class,您想将其用作 public 抽象基础 class 实现的一部分:

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 public。

(您可以使 SomeHelper 成为 Test 的受保护内部 class,但如果 SomeHelper 旨在供其他 class不是从基础 class.)

派生的

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

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

现在它会编译,你不必暴露你的内部结构。

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

受保护的内部

  • protected 在另一个程序集中:只能在子 类.

  • 中访问
  • internal in the current assembly: 当前程序集中的所有人都可以访问。

私人保护

  • private 在另一个程序集中:不可访问。
  • protected 在当前程序集中:只能在子 类.
  • 中访问