2016-09-19 9 views
0

したがって、基本的に2文字の配列であるabstractクラスの一部である以下のメソッドがあります。私は、少し違う振る舞いを持ついくつかのサブクラスを持つつもりです。それは、さまざまな方法で自分自身を埋める方法を知っています。C#:このメソッドをオーバーライドする方法を構造化する方法

問題のメソッドは、文字列を配列に挿入することになっています。オーバーフローエラーを避けるために、配列に空きがあるかどうかを確認する必要があります。これが十分な部屋かどうかを確認することは簡単ですが、問題が始まる場所です。

余裕がない場合は、各サブクラスでその動作をどのように処理するかを定義する必要があります。 (例えば、いくつかのサブクラスは最初からやり直して、何もしないで文字の挿入をやめ、上の行を消去し、すべてを上に移動し、下の新しい空白行に書きます。プログラムをクラッシュさせるなど)

次のコードのコメントを参照してください。私はoverrideの実装をしたいと思うが、私はちょうどelseブランチをオーバーライドする方法があるのだろうか、またはサブクラスに全体のメソッドを移動する必要がありますか?

IsEnoughRoomは、クラス内のプライベートメソッドである。)

internal void InsertString(string stringToInsert, int xStart, int yStart) 
{ 
    char[] charsToInsert = stringToInsert.ToCharArray(); 
    int currentXPosition = xStart; 
    int currentYPosition = yStart; 

    // For each character in the array of charsToInsert, 
    for (int i = 0; i < charsToInsert.Length; i++) 
    { 
     // Check if there is enough room... 
     if(isEnoughRoom(xStart, yStart, charsToInsert)) 
     { 
      SetCharAt(currentXPosition, currentYPosition, charsToInsert[i]); 

      if (currentXPosition < xSize - 1) 
      { 
       currentXPosition++; 
      } 
      else 
      { 
       currentXPosition = 0; 
       currentYPosition++; 
      } 
     } 
     else 
     { 
      //TODO: What do we do if there isn't enough room? 
     } 
} 
+5

なぜ、 'else'ブランチで仮想メソッドまたは抽象メソッドを呼び出さないのですか?あなたが最初からやり直す方法ははっきりしません...私の推測では、あなたがelseブランチの中でやりたいと思っていることをすべて実際に表現することはできません。 –

+0

@JonSkeet私を訂正してくださいもし私が間違っていれば、私はそれをしたら方法の中のフィールドにアクセスすることができませんでしたか?つまり、 'currentYPosition'を' 0'に設定して最初からやり直すことはできません。それともコンセプトが欠けていますか? – Airhead

+0

さて、メソッドを参照することによって変数を渡す可能性があります。戻り値を使用することもできます。 (または、それらをすべて単一のオブジェクトにカプセル化したいと思うかもしれません...)しかし、それは、その別の場合にその 'else'ブランチのボディがどのように見えるかを示すことが非常に役立つでしょう。 –

答えて

1

あり、あなたの抽象クラスのメソッドがvirtualである可能性、代替的なアプローチだと、それは結果であったかを決定する列挙値を返すことができますし、発信者に残りをさせてください。呼び出し側全体を派生クラスにすることができます。

のはアクションでこのソリューションを見てみましょう:

public enum CharInsertionResult 
{ 
    Success, 
    NoRoom 
} 

public abstract class CharInserter 
{ 
    internal virtual CharInsertionResult InsertString(string stringToInsert, int xStart, int yStart) 
    { 
     char[] charsToInsert = stringToInsert.ToCharArray(); 
     int currentXPosition = xStart; 
     int currentYPosition = yStart; 

     // For each character in the array of charsToInsert, 
     for (int i = 0; i < charsToInsert.Length; i++) 
     { 
      // Check if there is enough room... 
      if(isEnoughRoom(xStart, yStart, charsToInsert)) 
      { 
       SetCharAt(currentXPosition, currentYPosition, charsToInsert[i]); 

       if (currentXPosition < xSize - 1) 
       { 
        currentXPosition++; 
       } 
       else 
       { 
        currentXPosition = 0; 
        currentYPosition++; 
       } 

       return CharInsertionResult.Success 
      } 
      else 
      { 
       return CharInsertionResult.NoRoom; 
      } 
     } 
    } 
} 

今派生クラスがCharInsertionResult.NoRoomケースへの解決策を提供する抽象クラスの実装をオーバーライドすることができます

public class SpecializedCharInserter : CharInserter 
{ 
    internal override CharInsertionResult InsertString(string stringToInsert, int xStart, int yStart) 
    { 
      CharInsertionResult result = base.InsertString(stringToInsert, xStart, yStart); 

      switch(result) 
      { 
       case CharInsertionResult.NoRoom: 
         // Do stuff here to handle this scenario 
         break; 

       default: 
         return result; 
      } 
    } 
} 

IMHO、私はそれがだと信じていますあなたがメソッドをオーバーライドする必要はありませんNoRoomシナリオを処理したくない場合、良いデザインです。そうでなければ、派生クラスで拡張性のポイントを持っています。

+0

しかし、私は一度に1つのクラスだけをサブクラス化することができ、InsertStringを含むクラスには、CharInserterクラス内の適切でない責任を果たすために必要な他のメソッドがあります。あるいは私は誤解していますか? – Airhead

+0

@HCBPshenanigans特定のサブクラスにこれらのメソッドが必要な場合は、それらを 'protected'にする必要があります。私は間違っていますか? –

+0

私はあなたの答えを読んで、今それをよく理解しています。私がちょうどノートパソコンから離れて戻ってくる前に何かについて考える必要があったことが分かります。あなたが何を意味しているか分かったので、これは良い方法だと思います。ありがとう! – Airhead

関連する問題