22

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

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 = ...

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

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

4

3 回答 3

27

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

Private,通过在成员声明中包含 private 修饰符来选择。private 的直观含义是“仅限于包含类型的访问”。

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

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

直观地说,当访问类型或成员 M 时,会评估以下步骤以确保允许访问:

  • 首先,如果 M 在一个类型中声明(与编译单元或命名空间相反),如果该类型不可访问,则会发生编译时错误。
  • 然后,如果 M 是公共的,则允许访问。
  • 否则,如果 M 是受内部保护的,则如果访问发生在声明 M 的程序中,或者如果访问发生在从声明 M 的类的派生类中并通过派生类类型发生(§ 3.5.3)。
  • 否则,如果 M 受保护,如果访问发生在声明 M 的类中,或者如果访问发生在从声明 M 的类派生的类中并通过派生类类型发生(第 3.5 节),则允许访问.3)。
  • 否则,如果 M 是内部的,则如果访问发生在声明 M 的程序中,则允许访问。
  • 否则,如果 M 是私有的,则如果访问发生在声明 M 的类型中,则允许访问。
  • 否则,类型或成员不可访问,并发生编译时错误。
于 2011-04-20T23:06:38.603 回答
7

这是一种常见的设计。假设编写该类的人都知道如何正确使用它,并理解直接访问私有成员的含义。因此,访问同一类的其他实例的私有成员通常是可行的。如果你熟悉 C++ 的friend构造,那么就像同一个类的实例都是彼此的朋友(尽管 C#friend官方没有这个概念)。

这适用于 C# 和 Java,这两种语言是我脑海中最熟悉的两种语言。我敢打赌,许多其他语言也允许这样做(有人想插话吗?)

于 2011-04-20T23:02:18.217 回答
3

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

这已经在这里讨论过。我们可以使用对象访问私有变量吗

于 2011-04-20T23:11:09.210 回答