一尘不染

为什么专用字段专用于类型而不是实例专用?

c#

在C#(和许多其他语言)中,访问相同类型其他实例的私有字段是完全合法的。例如:

public class Foo
{
    private bool aBool;

    public void DoBar(Foo anotherFoo)
    {
        if (anotherFoo.aBool) ...
    }
}

正如C#规范(第3.5.1节,第3.5.2节)所述,对私有字段的访问是基于类型的,而不是实例。我一直在与一位同事讨论此问题,我们正在尝试提出其工作原理的原因(而不是限制对同一实例的访问)。

我们能想到的最好的参数是进行相等性检查,其中类可能要访问私有字段来确定与另一个实例的相等性。还有其他原因吗?还是某些绝对的理由绝对意味着它必须像这样工作,否则某些事情将完全不可能?


阅读 264

收藏
2020-05-19

共1个答案

一尘不染

我认为以这种方式工作的原因之一是因为访问修饰符在 编译时 起作用。因此,确定给定对象是否也是 当前 对象并不容易。例如,考虑以下代码:

public class Foo
{
    private int bar;

    public void Baz(Foo other)
    {
        other.bar = 2;
    }

    public void Boo()
    {
        Baz(this);
    }
}

编译器可以确定other实际上是this吗?并非在所有情况下都如此。有人可能会争辩说,那时不应该编译它,但这意味着我们有一个代码路径,无法访问
正确实例 的私有实例成员,我认为这更糟。

只有需要的类型级而非对象级可视性确保问题是容易处理的,以及做这似乎是它的情况 应该 工作 实际 的工作。

编辑 :Danilel
Hilgarth的观点是有道理的。语言设计者可以创建所需的语言,并且编译器编写者必须遵守该语言。话虽这么说,语言设计人员确实有一定的动力去使编译器编写者更容易地完成工作。(尽管在这种情况下,很容易争辩说,然后
只能 通过this(隐式或显式)访问私有成员)。

但是,我认为这使问题比需要解决的更加混乱。如果上面的代码不起作用,大多数用户(包括我自己)会发现它不必要地限制了它:毕竟,这就是
要访问的数据!我为什么要经历this

简而言之,我认为我可能夸大了这种情况,因为它对编译器“困难”。我真正想传达的是,上述情况似乎是设计师希望进行的工作。

2020-05-19