Reputation: 67335
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?
Upvotes: 4
Views: 2607
Reputation: 27039
You need to provide implementation for the ToText()
method in the derived class, but you are calling the base class ToText()
method within the implementation and that does not make sense. Imagine you tried this, this will not work either:
public class HtmlNode : Node
{
protected override string ToText()
{
base.ToText(); // Will not compile: Cannot call abstract base member
}
}
Things become more clear if you use the HtmlNode
class. So let's use it:
HtmlNode node = new HtmlNode();
node.ChildNodes.Add(new HtmlNode());
node.ChildNodes.Add(new NodeB()); // Say NodeB inherits Node
Does it make sense for HtmlNode
to call ToText()
method of NodeB
? No it does not because HtmlNode
does not inherit NodeB
so why should it be allowed to access the protected
methods of NodeB
?
Upvotes: 0
Reputation: 34234
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.
Upvotes: 9