Could not access protected method in derived class

I don't understand why this code is giving me 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 above, I get the error:

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

HtmlNode

comes from Node

, so why HtmlNode

can't you access protected members Node

?

And how do I change the code to use a "type specifier HtmlNode

" as suggested in the error message?

+3


source to share


2 answers


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

According to MSDN, the keyword protected

means the following:

protected

- access is restricted to classes containing the class or derived from the containing class .

Now imagine the compiler allows you to compile it and now you are iterating through your collection and calling the method .ToText()

.

If it node

is HtmlNode

or is a subclass of it, you can call this method.



However, if node

is a kind of type AnotherNode

:

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

      

In this case, you are trying to call a protected ToText

class method AnotherNode

.
Are you "the containing class (AnotherNode)"? Not.
Are you a "type derived from AnotherNode"? Not.
So it looks like you shouldn't be able to access this method.

Since they ChildNodes

are instances of types that are not known at compile time, the compiler cannot determine whether you should have access to its method or not.
This is how I understand why the compiler is throwing this exception.

+8


source


You need to provide an implementation for the method ToText()

in the derived class, but you are calling the base class method ToText()

in the implementation and that doesn't make sense. Imagine you tried this, it won't work either:

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

      

Things become clearer if you use the class HtmlNode

. So let's use it:



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

      

Could it make sense to HtmlNode

call a method ToText()

NodeB

? No, it doesn't, because it HtmlNode

doesn't inherit NodeB

, so why should it be allowed to access protected

methods NodeB

?

+1


source







All Articles