当 C# 位于同一包含类中时,为什么以及如何允许访问类本身之外的私有变量?

问题描述 投票:0回答:3

我不知道这个问题是否具有足够的描述性,但是这种行为为什么以及如何存在?:

public class Layer
{
    public string Name { get; set; }

    private IEnumerable<Layer> children;
    public IEnumerable<Layer> Children
    {
        get { return this.children.Where ( c => c.Name != null ).Select ( c => c ); }
        set { this.children = value; }
    }

    public Layer ( )
    {
        this.children = new List<Layer> ( ); // Fine

        Layer layer = new Layer ( );
        layer.children = new List<Layer> ( ); // Isn't .children private from the outside?
    }
}

我可以在任何地方访问

layer.Children
,这很好,但是由于它是私有的,我如何访问
layer.children

Layer layer = new Layer ( );
layer.children = new List<Layer> ( );

仅当代码位于

Layer
类内部时才有效。如果访问私有变量是在包含类内部完成的,是否有特殊的代码来以不同的方式处理访问私有变量,即使访问是从外部进行的?

我知道使用原因了:

this.children = ...

在包含类内部,但创建新实例并从外部修改它们,即使它们仍在包含类中,似乎也不是一个好的做法。

允许这样做的原因是什么?

c# .net class private-members
3个回答
32
投票

参见 C# 语言规范第 3.5.1 节。相关文字是这样的:

Private,由以下人员选择 包括一个私有修饰符 会员声明。直观的 private 的意思是“访问受限 到包含类型”。

请注意,修饰符与 类型相关,而不是 实例。

然后在第 3.5.2 节中进一步解释了一些规则:

用直观的术语来说,当一个类型或 成员M被访问,如下 评估步骤以确保 允许访问:

  • 首先,如果 M 是在类型中声明的(而不是编译单元) 或命名空间),编译时错误 如果该类型不可访问,则会发生。
  • 然后,如果M是public,则允许访问。
  • 否则,如果 M 受到内部保护,则在以下情况下允许访问: 它发生在程序中 M 被声明,或者如果它出现在 从类中派生的类 其中 M 被声明并发生 通过派生类类型 (§3.5.3)。
  • 否则,如果M受到保护,如果发生则允许访问 在 M 所在的类中 声明,或者如果它发生在 类派生自其中的类 M 的声明和发生通过 派生类类型 (§3.5.3)。
  • 否则,如果M是内部的,则如果发生则允许访问 在 M 为的程序中 宣布。
  • 否则,如果M是私有的,则如果发生则允许访问 在 M 为的类型中 宣布。
  • 否则,类型或成员不可访问,并出现编译时错误 发生。

7
投票

这是常见的设计。假设编写该类的人都知道如何正确使用该类,并理解直接访问私有成员的含义。因此,访问同一类的其他实例的私有成员通常是有效的。如果您熟悉 C++ 的

friend
构造,那么就好像同一类的实例都是彼此的朋友(尽管 C# 正式没有
friend
概念)。

这适用于 C# 和 Java,这是我立刻就知道的两种语言。我敢打赌许多其他语言也允许这样做(有人想插话吗?)


3
投票

请记住,私有访问修饰符表示

Private members are accessible only within the body of the class or the struct in which they are declared
。这个描述令人困惑,但它清楚地表明限制是在班级级别和
NOT OBJECT LEVEL
。在这种情况下,图层仍在类中。

这个问题之前已经讨论过。 我们可以使用对象访问私有变量吗

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.