(C#7.2)“私有保护”修饰符的用例是什么?

时间:2017-11-22 09:01:22

标签: c# .net access-modifiers c#-7.2

C# 7.2 introduces the private protected modifier

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

我试图理解为什么C#语言团队添加了此功能。在谷歌上进行了广泛的搜索,阅读并观看了“最新的”媒体(我已经看过press releasedetailsvideo by Mads Torgerson),我仍然没有更聪明。< / p>

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

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

3 个答案:

答案 0 :(得分:59)

在C#7.2之前,我们有protected internal修饰符。这实际上意味着受保护的OR内部,即 - 成员A可供子类以及当前程序集中的任何类访问,即使该类不是类A的子类(因此, “受保护的”是放松的。)

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

我们可以举例说明Jon Skeet提供in comments。假设你有课

public class MyClass {

}

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

使用内部构造函数

可以实现仅在当前程序集中继承
public class MyClass {
    internal MyClass() {
    }
}

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

public class MyClass {
    protected MyClass() {
    }
}

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

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

答案 1 :(得分:8)

让我们假设您有一个名为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();
}

现在它将编译,你不必暴露你的内部。

答案 2 :(得分:7)

对于双字访问修饰符,我有这个概念 - 第一个访问器与另一个组件相关,第二个访问器与定义它的组件相关。

受保护的内部

    另一个程序集中的
  • protected :只能在子类中访问。

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

私人保护

    另一个程序集中的
  • 私有:无法访问。
  • 当前程序集中的
  • protected :只能在子类中访问。