无法访问派生 class 中的受保护方法

Unable to access protected method in derived class

我不明白为什么这段代码给我一个 Intellisense 错误。

public abstract class Node
{
    protected abstract string ToText();
}

public class HtmlNode : Node
{
    public List<Node> ChildNodes { get; set; }

    protected override string ToText()
    {
        StringBuilder builder = new StringBuilder();

        foreach (var node in ChildNodes)
            builder.Append(node.ToText());  // <=== THIS IS THE ERROR

        return builder.ToString();
    }
}

在上面指出的行中,我收到错误:

Error CS1540: Cannot access protected member 'Node.ToText()' via a qualifier of type 'Node'; the qualifier must be of type 'HtmlNode' (or derived from it)

HtmlNode 派生自 Node,那么为什么 HtmlNode 不能访问 Node 的受保护成员?

我该如何修改代码以按照错误消息中的建议使用 "a qualifier of type HtmlNode"

据我所知,你可以通过继承机制访问受保护成员,但你仍然不能通过实例访问受保护成员。

根据 MSDN,protected 关键字的含义如下:

protected - Access is limited to the containing class or types derived from the containing class.

现在,让我们假设编译器让您编译它,现在您正在遍历您的集合并调用 .ToText() 方法。

如果 node 是一个 HtmlNode 或其子class,那么您可以调用此方法。

但是,如果 node 是某种类型 AnotherNode:

public class AnotherNode : Node
{
    protected override string ToText()
    {
    }  
}

在这种情况下,您正在尝试调用 AnotherNode class.
的受保护 ToText 方法 你是 "containing class (AnotherNode)" 吗?号
你是 "type derived from AnotherNode" 吗?号
所以,看起来你不应该能够访问这个方法。

由于 ChildNodes 是编译时未知的类型实例,编译器无法确定您是否应该访问其方法。
这就是我如何理解编译器抛出此异常的原因。

您需要在派生的 class 中为 ToText() 方法提供实现,但您在实现中调用基础 class ToText() 方法,这确实没有意义。想象一下你试过这个,这也行不通:

public class HtmlNode : Node
{
    protected override string ToText()
    {
        base.ToText(); // Will not compile: Cannot call abstract base member
    }
}

如果使用 HtmlNode class,事情会变得更加清晰。所以让我们使用它:

HtmlNode node = new HtmlNode();
node.ChildNodes.Add(new HtmlNode());
node.ChildNodes.Add(new NodeB()); // Say NodeB inherits Node

HtmlNode调用NodeBToText()方法有意义吗?不,不是因为 HtmlNode 不继承 NodeB 那么为什么要允许它访问 NodeBprotected 方法?