2017-07-11 16 views
3

なぜこのコードで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)

HtmlNodeNodeから派生し、そのNodeのなぜできないHtmlNodeアクセス保護されたメンバー?

"HtmlNodeタイプの修飾子"を使用するようにコードを修正するにはどうすればよいですか?

+0

問題は、Childnodesのリストが抽象ノードのリストであることです。それは意味をなさない。抽象Nodeクラスは、HTMLNODEクラスのように実装する必要があります。それを見るには子ノードをリストに変更する ... –

+1

@JohnPeters:私は抽象化を使用しているので、それは完璧な意味合いがあると主張します。私は 'Node'のいくつかのサブクラスを持つことができ、それらのすべてに共通のこのメソッドにアクセスできるはずです。あなたの回避策は 'HtmlNode'型のノードでしか動作しません。それは私が必要とするものではありません。 –

+1

@AzarShaikh 'node'が' HtmlNode'でない場合、クラッシュします。 –

答えて

8

私はそれを見ると、継承メカニズムによって保護されたメンバーにアクセスできますが、インスタンスを通じて保護されたメンバーにアクセスすることはできません。

MSDNによると、protectedキーワードは次のことを意味します。今すぐ

protected - Access is limited to the containing class or types derived from the containing class.

、のコンパイラは、あなたがそれをコンパイルし、今あなたのコレクションを反復処理し、.ToText()メソッドを呼び出していることができます想像してみましょう。

nodeHtmlNodeまたはそのサブクラスの場合、このメソッドを呼び出すことができます。

nodeはタイプAnotherNodeのいくつかの並べ替えている場合しかし、この場合には

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

、あなたは保護されたAnotherNodeクラスのToTextメソッドを呼び出そうとしています。
「クラスを含む(AnotherNode)」ですか?いいえ。
"AnotherNodeから派生したタイプ"ですか?いいえ。
このメソッドにアクセスできないように見えます。

ChildNodesはコンパイル時に知られていない型のインスタンスなので、コンパイラはメソッドにアクセスする必要があるかどうかを判断できません。
これは、コンパイラがこの例外をスローする理由を示しています。

+2

これは答えだと思います。私がC++でプログラミングした時、これは完全にうまくいっていることを思い出します。 C#で許可されていれば便利です。 –

1

派生クラスでToText()メソッドの実装を提供する必要がありますが、実装内で基底クラスToText()メソッドを呼び出すと意味がありません。あなたはこれを試してみました想像し、これはどちらか動作しません:あなたはHtmlNodeクラスを使用する場合

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

物事はより明確になります。それでは、それを使ってみましょう:HtmlNodeNodeBToText()メソッドを呼び出すようにするために

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

それは理にかなっていますか? HtmlNodeNodeBを継承していないので、なぜprotectedの方法をNodeBにアクセスする必要があるのでしょうか?

+1

これは、仮想関数のためのものです。それは完璧な意味合いがあります。 –

+0

@JonathanWoodしかし、それは仮想ではありません。それは抽象的です。 C#では、それらは異なって扱われます。 – CodingYoshi

+0

抽象メソッドは自動的に仮想です。それ以外の場合、それらを実装する方法はありません。 –

関連する問題