无法访问派生 class 中的受保护方法
Unable to access protected method in derived class
我不明白为什么这段代码给我一个 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();
}
}
在上面指出的行中,我收到错误:
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
派生自 Node
,那么为什么 HtmlNode
不能访问 Node
的受保护成员?
我该如何修改代码以按照错误消息中的建议使用 "a qualifier of type HtmlNode
"?
据我所知,你可以通过继承机制访问受保护成员,但你仍然不能通过实例访问受保护成员。
根据 MSDN,protected
关键字的含义如下:
protected
- Access is limited to the containing class or types derived from the containing class.
现在,让我们假设编译器让您编译它,现在您正在遍历您的集合并调用 .ToText()
方法。
如果 node
是一个 HtmlNode
或其子class,那么您可以调用此方法。
但是,如果 node
是某种类型 AnotherNode
:
public class AnotherNode : Node
{
protected override string ToText()
{
}
}
在这种情况下,您正在尝试调用 AnotherNode
class.
的受保护 ToText
方法
你是 "containing class (AnotherNode)" 吗?号
你是 "type derived from AnotherNode" 吗?号
所以,看起来你不应该能够访问这个方法。
由于 ChildNodes
是编译时未知的类型实例,编译器无法确定您是否应该访问其方法。
这就是我如何理解编译器抛出此异常的原因。
您需要在派生的 class 中为 ToText()
方法提供实现,但您在实现中调用基础 class ToText()
方法,这确实没有意义。想象一下你试过这个,这也行不通:
public class HtmlNode : Node
{
protected override string ToText()
{
base.ToText(); // Will not compile: Cannot call abstract base member
}
}
如果使用 HtmlNode
class,事情会变得更加清晰。所以让我们使用它:
HtmlNode node = new HtmlNode();
node.ChildNodes.Add(new HtmlNode());
node.ChildNodes.Add(new NodeB()); // Say NodeB inherits Node
HtmlNode
调用NodeB
的ToText()
方法有意义吗?不,不是因为 HtmlNode
不继承 NodeB
那么为什么要允许它访问 NodeB
的 protected
方法?
我不明白为什么这段代码给我一个 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();
}
}
在上面指出的行中,我收到错误:
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
派生自 Node
,那么为什么 HtmlNode
不能访问 Node
的受保护成员?
我该如何修改代码以按照错误消息中的建议使用 "a qualifier of type HtmlNode
"?
据我所知,你可以通过继承机制访问受保护成员,但你仍然不能通过实例访问受保护成员。
根据 MSDN,protected
关键字的含义如下:
protected
- Access is limited to the containing class or types derived from the containing class.
现在,让我们假设编译器让您编译它,现在您正在遍历您的集合并调用 .ToText()
方法。
如果 node
是一个 HtmlNode
或其子class,那么您可以调用此方法。
但是,如果 node
是某种类型 AnotherNode
:
public class AnotherNode : Node
{
protected override string ToText()
{
}
}
在这种情况下,您正在尝试调用 AnotherNode
class.
的受保护 ToText
方法
你是 "containing class (AnotherNode)" 吗?号
你是 "type derived from AnotherNode" 吗?号
所以,看起来你不应该能够访问这个方法。
由于 ChildNodes
是编译时未知的类型实例,编译器无法确定您是否应该访问其方法。
这就是我如何理解编译器抛出此异常的原因。
您需要在派生的 class 中为 ToText()
方法提供实现,但您在实现中调用基础 class ToText()
方法,这确实没有意义。想象一下你试过这个,这也行不通:
public class HtmlNode : Node
{
protected override string ToText()
{
base.ToText(); // Will not compile: Cannot call abstract base member
}
}
如果使用 HtmlNode
class,事情会变得更加清晰。所以让我们使用它:
HtmlNode node = new HtmlNode();
node.ChildNodes.Add(new HtmlNode());
node.ChildNodes.Add(new NodeB()); // Say NodeB inherits Node
HtmlNode
调用NodeB
的ToText()
方法有意义吗?不,不是因为 HtmlNode
不继承 NodeB
那么为什么要允许它访问 NodeB
的 protected
方法?