【问题标题】:Accessing inherited private base class member...through derived class object...created in base class member访问继承的私有基类成员...通过派生类对象...在基类成员中创建
【发布时间】:2012-06-10 23:59:41
【问题描述】:

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

    }
}

【问题讨论】:

  • 不确定问题出在哪里。 xy 只能在 a 的成员中访问,即使它们被基类继承和使用。

标签: c# inheritance


【解决方案1】:

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

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

注意这一行:

int rr = b.y;

被有效地转换为

int rr = a.y;

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

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

【讨论】:

  • @MareInfinitus: base.b 没有任何意义 - b 是类型名称。我建议你编写你想要检查它是否真的有意义的代码......
  • 就是这样!斯基特先生的回答恰到好处。谢谢大家!
  • @MareInfinitus:当然,当您尝试使用bobj 时,这些将无效...
【解决方案2】:

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

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

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

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

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

...由于需要显式类型转换或使用反射,因此不太可能意外发生。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-04-14
    • 2017-12-15
    • 1970-01-01
    • 1970-01-01
    • 2021-12-05
    • 2013-02-12
    • 1970-01-01
    • 2017-08-07
    相关资源
    最近更新 更多