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?
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.