Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
(C#7.2)的用例是什么;“私人保护”;修饰语?_C#_.net_Access Modifiers_C# 7.2 - Fatal编程技术网

(C#7.2)的用例是什么;“私人保护”;修饰语?

(C#7.2)的用例是什么;“私人保护”;修饰语?,c#,.net,access-modifiers,c#-7.2,C#,.net,Access Modifiers,C# 7.2,我一直保护对具有属性的字段的访问,允许通过Get/Set方法进行访问,因为我通常不希望对象的内部状态被我自己的类以外的任何东西修改 我试图理解为什么C语言团队添加了这个特性。在谷歌上进行了广泛的搜索,阅读和观看了“最新消息”媒体(我已经看了,和),我仍然没有变得更聪明 在我看来,这似乎允许开发人员打破Liskov替换原则,但这可能是因为我不理解为什么现在存在此功能 我理解如何使用它,只是不理解为什么-请有人提供一个真实世界的使用示例,而不是MSDN文档中的人为示例?在C#7.2之前,我们有受保护

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

我试图理解为什么C语言团队添加了这个特性。在谷歌上进行了广泛的搜索,阅读和观看了“最新消息”媒体(我已经看了,和),我仍然没有变得更聪明

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

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

在C#7.2之前,我们有
受保护的内部
修饰符。这实际上意味着受保护的或内部的,即子类和当前程序集中的任何类都可以访问-member
A
,即使该类不是class
A
的子类(因此“protected”所暗示的限制被放宽)

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

我们可以举一个例子。假设你有课

public class MyClass {

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

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

public class MyClass {
    internal MyClass() {
    }
}
使用受保护的构造函数可以防止直接实例化,除非使用当前类层次结构:

public class MyClass {
    protected MyClass() {
    }
}
public class MyClass {
    private protected MyClass() {
    }
}
要同时获得这两项功能,您需要
受私有保护的
构造函数:

public class MyClass {
    protected MyClass() {
    }
}
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();
}
现在它将被编译,您不必公开内部组件。

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

受保护的内部

  • 在另一个程序集中受保护:仅在子类中可访问

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

私人保护

  • 另一程序集中的专用:不可访问
  • 在当前程序集中受保护:仅在子类中可访问

你确定你理解这个修饰符的实际功能吗?它与受保护的
非常相似,但有一个重要的区别:如果一个类是从它派生的,但在另一个程序集中,它不能访问这个成员,而受保护的
不限于同一个程序集。下面是一个我计划使用它的示例,如果有任何帮助:@Evk:因为我确实希望直接从查询中实例化它。查询可以是一个具体的类,也可以有一个子类,但只能在同一个程序集中。其他代码创建
Query
的实例是不合适的<代码>私人保护
将为我提供我想要的。有关此方面的一些想法,请参阅。这项功能花了十五年时间才得以实现,原因是:它不是一项非常引人注目、有趣或有用的功能。@TimSchmelter从某种意义上讲,它们都涉及对子类(受保护)和当前程序集(内部)的限制。他们只是以不同的方式将这些限制结合起来(和vs或)。对不起,删除了我的评论,因为它是基于意见的。但我仍然认为受保护的
比受保护的内部
更“相似”(非常令人困惑的访问修饰符,因为公共程序集是明智的)。
protected
access修饰符具有相同的约定:只能在从该修饰符派生的相同类型内访问。但它的范围并不限于此程序集,而不是
私有内部
。因此,如果一个成员受
保护
,但您必须避免从程序集外部访问它,那么您需要
受私有保护
。因此,通过阅读。我不明白的是,为什么你会想做他们描述的事情——从派生类(在同一个程序集中)访问基类上的字段,而不引入属性。如果这个例子和你的一样,那么它就非常有意义(我喜欢你描述受保护的内部和私有保护之间的区别的方式)。也许我只是对MSDN示例有偏见@Jay嗯,您不应该期望MSDN示例有太多的现实意义(据我所知,您的主要抱怨是他们使用的是受保护字段,甚至与它是否仅受保护或“私人保护”无关)。毕竟这不是最好的设计范例