0

我无法理解为什么 a 类中的 m() 可以通过 b 类和 b 类对象访问 x 和 y,如果 x 和 y 是私有的。我知道当 b 从 a 继承时,b 从 a 接收私有成员,即使它们不能被 b 使用。但奇怪的是b成员不能使用x和y,而a以外的类不能通过b类和b类对象获取变量,而m()却可以通过b访问x和y类和 b 类对象。

有人可以使用我错过的一般规则向我解释这一点,或者可能解释编译器如何将基成员“给予”派生类?

class a
{
    private int x;
    private static int y;

    static void m()
    {
        b bobj = new b();
        int mm = bobj.x;
        int rr = b.y;


    }

    void n()
    {
        b bobj = new b();
        int mm = bobj.x;
        int rr = b.y;
    }
}

class b : a
{
    private int u;
    private static int v;

    static void o()
    {

    }

    void p()
    {

    }
}
4

2 回答 2

3

我无法理解为什么 a 类中的 m() 可以通过 b 类和 b 类对象访问 x 和 y,如果 x 和 y 是私有的

类声明中的代码可以访问该类声明的任何私有成员——就这么简单。所以里面的代码a不能访问在 中声明的私有变量b,但它可以a通过一个实例访问在 中声明的私有变量,该实例a也恰好是b.

请注意,这一行:

int rr = b.y;

有效地转换为

int rr = a.y;

y仅由 声明a- 如果它真的由 声明b,它将无法访问。

有关详细信息,请参阅 C# 4 语言规范的第 3.5 节。

于 2012-06-10T15:37:15.387 回答
0

这是从 C++ 语言继承的规则。

private并对protected类进行操作,而不是对象。因此,例如,如果您有一个Bank对象,它的成员可以访问任何其他Bank人的私人数据,尽管这可能看起来违反直觉或危险。

因为 C++ 广泛使用指针算法和无限类型转换,所以在同一进程中执行任何代码之前,无法可靠地保护进程内的数据。

但是,如果您只需要防止意外访问的对象级保护,则可以通过定义一个接口并仅在银行之间传递接口来帮助您。虽然Bank对象仍然可以执行以下操作:

void TransferMoneyFrom(IBank otherBank, decimal theirAccountNumber,
                        decimal receivingAccountNumber, int amount)
{
    ((Bank)otherBank).PrivateProperty = whatever;
}

...它不太可能无意中发生,因为需要显式类型转换或使用反射。

(请注意,C# 通常可以更轻松地有意访问您没有源代码的某个其他的私有成员(按名称,使用反射)。如​​果该类型的供应商认为这是一个劣势,他们可以使用一个混淆器使这变得更加困难。这仍然不能以任何方式保护被混淆的对象免受其自身的其他实例的影响。)

于 2012-06-10T15:38:53.883 回答