无法从派生类访问受保护的成员

时间:2015-03-31 13:22:45

标签: c# scope protected derived-class

所以我刚刚发现C#编译器看起来很奇怪(至少对我来说)。

请看下面的演示代码:

public class Program
{
    public static void Main(string[] args)
    {
        ChildClass c = new ChildClass();
        c.parentInstance = new ChildClass();
        c.ChildPublicMethod();
        Console.ReadKey();
    }
}

public class ParentClass
{
    public ParentClass parentInstance = null;

    protected void ProtectedMethod(string arg)
    {
        Console.WriteLine("Arg=\"{0}\"", arg);
    }

    public void ParentPublicMethod()
    {
        ProtectedMethod("Parent's public method.");
    }
}

public class ChildClass : ParentClass
{
    public void ChildPublicMethod()
    {
        ParentPublicMethod();
        ProtectedMethod("Child's protected method");

        ((ChildClass)parentInstance).ProtectedMethod(
                "A different child's protected method.");
        //parentInstance.ProtectedMethod(
        //      "A different child's protected method."); //Compile time error.
    }

}

ChildClass.ChildPublicMethod()函数中,我希望我可以通过注释掉的代码访问受保护的成员。毕竟,编译器是否应该拥有能够告诉它是安全访问的所有必要信息?它知道parentInstance的类型为ParentClass,它知道parentInstance是从ParentClass的后代访问的,那么编译器为什么还要抱怨?

显然,表演演员似乎可以解决所有问题。 那么这两个电话的区别究竟是什么:?

((ChildClass)parentInstance).ProtectedMethod(
        "A different child's protected method.");
//parentInstance.ProtectedMethod(
//      "A different child's protected method."); //Compile time

有感: 我能想到的唯一可能的解释是C#编译器需要100%确定parentInstance确实是ChildClass的后代。如果有一个班级,比如说ChildClass2 : ParentClass,那么从ChildClass开始访问受保护的成员是不正确的,因为ChildClass并非来自ChildClass2。转换为ChildClass会告诉编译器您希望parentInstanceChildClass个实例,而不是ParentClass的其他后代。

然而,我看到另一个问题。 假设我将变量设置为:

c.ParentInstance = new ParentClass();

在这种情况下,ChildClass无法访问受保护的方法(甚至不能使用强制转换,因为它无法转换为包含受保护方法的任何其他内容)。为什么会这样? 如果该实例显然是ParentClass而且仅此而已,为什么ChildClass无法访问其受保护的方法?或者有可能吗?

<小时/>

编辑:

显然,似乎对我所要求的内容存在误解。是的我意识到无法访问ParentClass实例。但是,我担心这背后的原因是什么,以便我能理解为什么

我的上述事后才是否正确?我理解这个吗?

感谢。

2 个答案:

答案 0 :(得分:1)

完全如你所说。 parentInstance 可能ChildClass2的实例,因此将该对象的受保护成员暴露给您的ChildClass会产生可能的安全威胁。

想象一下以下情况:
您有一个可扩展的类A,它将一些受保护的成员公开给它的派生类(例如,可能改变受保护状态或调用其他可能的虚拟成员)和派生类B,它们使用执行一些安全关键功能的基本功能,同时只暴露一个带有各种错误和权限检查的安全API。

现在,您真的希望任何人能够轻松绕过这些检查,只需从C派生一个类A,然后就可以直接调用{{1}类型的对象上的受保护方法}}?

答案 1 :(得分:1)

&#34;如果通过派生类类型进行访问,则只能在派生类中访问基类的受保护成员。&#34; < / p>

&#34;类型或成员只能通过相同的类或结构中访问,或的派生类中访问。&#34 ;

在您的代码行中:

parentInstance.ProtectedMethod("A different child's protected method.");

&#39;父辈&#39;不是来自&#39; ParentClass&#39; &#39; ParentClass&#39;。

在您的其他代码行中:

((ChildClass)parentInstance).ProtectedMethod("A different child's protected method.");

您只需告诉编译器将ParentClass对象视为ChildClass - 而ChildClass可以访问它继承的类的受保护成员。

但是,最终,代码将在运行时失败,因为ParentClass无法强制转换为ChildClass。

这有点难以解释,所以如果这没有完全合理,我会再试一次。 :)

(我看到你改变了你的问题,所以这可能不是你想要的。哼哼。)