Search code examples
c#.netoopaccess-modifiers

Unable to access protected method in derived class


I don't understand why this code gives me an Intellisense error.

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();
    }
}

On the line indicated above, I get the error:

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 derives from Node, so why can't HtmlNode access protected members of Node?

And how would I modify the code to use "a qualifier of type HtmlNode", as suggested in the error message?


Solution

  • As I see it, you can access protected members through inheritance mechanism, but you still cannot access protected members through instance.

    According to MSDN, protected keyword means the following:

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

    Now, let's imagine compiler lets you compile it and now you are iterating through your collection and call .ToText() method.

    If node is an HtmlNode or its subclass, then you are able to call this method.

    However, if node is some sort of type AnotherNode:

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

    In this case, you are trying to call protected ToText method of AnotherNode class.
    Are you a "containing class (AnotherNode)"? No.
    Are you a "type derived from AnotherNode"? No.
    So, it looks like you should not be able to access this method.

    Since ChildNodes are instances of types which are not known at compile time, compiler cannot determine if you should have access to its method or not.
    That's how I see why compiler throws this exception.