相关疑难解决方法(0)

通过base/sibling类阻止受保护成员访问的真正原因是什么?

我最近发现派生类中的方法只能通过派生类(或其子类之一)的实例访问基类的受保护实例成员:

class Base
{
    protected virtual void Member() { }
}

class MyDerived : Base
{
    // error CS1540
    void Test(Base b) { b.Member(); }
    // error CS1540
    void Test(YourDerived yd) { yd.Member(); }

    // OK
    void Test(MyDerived md) { md.Member(); }
    // OK
    void Test(MySuperDerived msd) { msd.Member(); }
}

class MySuperDerived : MyDerived { }

class YourDerived : Base { }
Run Code Online (Sandbox Code Playgroud)

我设法通过向基类添加静态方法来解决此限制,因为允许Base的方法访问Base.Member,而MyDerived可以调用该静态方法.

不过,我仍然不明白这种限制的原因.我已经看到了几个不同的解释,但他们无法解释为什么仍然允许MyDerived.Test()访问MySuperDerived.Member.

Principled说明:'受保护'意味着它只能被该类及其子类访问.YourDerived 可以覆盖Member(),创建一个只能由YourDerived及其子类访问的新方法.MyDerived无法调用重写的yd.Member()因为它不是YourDerived的子类,并且它不能调用b.Member(),因为b实际上可能是YourDerived的一个实例.

好的,但是为什么MyDerived可以调用msd.Member()?MySuperDerived可以覆盖Member(),并且只有MySuperDerived及其子类才能访问该覆盖,对吧?

直到运行时才知道您是否正在调用被覆盖的成员.当成员是一个字段时,它无论如何都不能被覆盖,但仍然禁止访问.

实用主义解释:其他类可能会添加您的类不了解的不变量,您必须使用它们的公共接口,以便它们可以维护这些不变量.如果MyDerived可以直接访问YourDerived的受保护成员,它可能会破坏这些不变量.

我同样的反对意见适用于此.MyDerived不知道MySuperDerived可能添加的不变量 - 它可能由不同的作者在不同的程序集中定义 - 为什么MyDerived可以直接访问其受保护的成员?

我得到的印象是,这种编译时限制是作为一种错误的尝试来解决一个实际上只能在运行时解决的问题.但也许我错过了一些东西.有没有人有这将通过类型YourDerived或基地的变量让MyDerived访问基地的保护成员造成的,但问题的例子不是 …

c# protected

14
推荐指数
2
解决办法
3739
查看次数

Java中的finalize方法

可能重复:
为什么java.lang.Object中的finalize()方法"受保护"?

finalize方法是使用受保护的作用域定义的,那么垃圾收集器等其他对象如何能够调用它.

java garbage-collection

1
推荐指数
1
解决办法
748
查看次数

标签 统计

c# ×1

garbage-collection ×1

java ×1

protected ×1