我不明白为什么这段代码会给我一个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();
}
}
在上面指出的行上,我收到错误:
错误CS1540:无法通过类型为“Node”的限定符访问受保护成员'Node.ToText()';限定符必须是'HtmlNode'类型(或从中派生出来)
HtmlNode
来自Node
,为什么HtmlNode
无法访问Node
的受保护成员?
如何修改代码以使用“HtmlNode
类型的限定符”,如错误消息中所示?
答案 0 :(得分:9)
在我看来,您可以通过继承机制访问受保护的成员,但您仍然无法通过实例访问受保护的成员。
根据MSDN,protected
关键字表示以下内容:
protected
- 访问仅限于包含类或从包含类派生的类型。
现在,让我们想象编译器让你编译它,现在你正在迭代你的集合并调用.ToText()
方法。
如果node
是HtmlNode
或其子类,则可以调用此方法。
但是,如果node
是某种类型AnotherNode
:
public class AnotherNode : Node
{
protected override string ToText()
{
}
}
在这种情况下,您尝试调用ToText
类的受保护AnotherNode
方法
你是一个&#34;包含类(AnotherNode)&#34;?第
你是来自AnotherNode&#34;的#34;类型吗?第
因此,看起来您应该无法访问此方法。
由于ChildNodes
是编译时未知的类型实例,因此编译器无法确定您是否应该访问其方法。
这就是我如何看待编译器抛出此异常的原因。
答案 1 :(得分:1)
您需要在派生类中为ToText()
方法提供实现,但是您在实现中调用基类ToText()
方法并且没有意义。想象一下,你试过这个,这也行不通:
public class HtmlNode : Node
{
protected override string ToText()
{
base.ToText(); // Will not compile: Cannot call abstract base member
}
}
如果您使用HtmlNode
课程,事情会变得更加清晰。所以让我们使用它:
HtmlNode node = new HtmlNode();
node.ChildNodes.Add(new HtmlNode());
node.ChildNodes.Add(new NodeB()); // Say NodeB inherits Node
HtmlNode
调用ToText()
NodeB
方法是否有意义?不,不是因为HtmlNode
没有继承NodeB
所以为什么要允许它访问protected
的{{1}}方法?