2012-03-29 4 views
1

現在、リストを作成するC#プログラムで作業しています。オブジェクトTaskは基本クラスであり、他の多くはそれを継承しています。私がしたいのは、リスト内のオブジェクトの1つのタイプを比較して、編集するためにどのフォームを開くべきかを調べることです。継承が使用されている場合にリストの型をチェックする方法

これは既に作成したコードです。二ノートで

private void itemEdit_Click(object sender, EventArgs e) 
    { 
     int edi = taskNameBox.SelectedIndex; 
     Task checkTask = todoList.ElementAt(edi); 

     if(checkTask.GetType is Note) 
     { 
      noteBuilder editNote = new noteBuilder(todoList); 
      editNote.Show(); 
     } 

     else if(checkTask.GetType is extendedTask) 
     { 
      extendedTaskBuilder editTask = new extendedTaskBuilder(todoList); 
      editTask.Show(); 
     } 

     else if(checkTask.GetType is Reminder) 
     { 
      reminderBuilder editReminder = new reminderBuilder(todoList); 
      editReminder.Show(); 
     } 

     else if (checkTask.GetType is Appointment) 
     { 
      appointmentBuilder editAppointment = new appointmentBuilder(todoList); 
      editAppointment.Show(); 
     } 
    } 

代わりに、フォーム間のリストを渡すと、私だけではなく、フォームとの間で単一のオブジェクトを渡すことの情報を表示するフォームの新しいオブジェクトを生成するすべてのフォームを更新するかどうかは容易になるだろう新しい要素がリストに追加される時刻。

感謝

+0

なぜ型に含まれている項目の1つのみをチェックするときに、完全なtodolistをビルダーに渡していますか?リストを編集するのか、選択した1つのアイテムだけを編集しますか? – Marcel

+0

@マルセルおそらく彼はそれを渡していません。メンバー変数にすることができます。 WillzSawyer、あなたは実際に答えを持っています。 – nawfal

+0

OKですが、さらに混乱します。私には、質問はかなり不明であり、受け入れられた答えは合理的な方法で質問と一致しません。病気 'は質問に-1を与える。 – Marcel

答えて

1

あなたはこのようにチェックしようとしたことがあり:

if (checkTask is Note) 
{ 

} 
... 
+0

これはその答えです。よくできました。 – nawfal

1

をあなたは今の間でスイッチングおよび仮想(抽象)メソッドを呼び出しているすべてのタイプの基本クラスを作成すると考えていますか?

すべてのコードを、オーバーライドされた抽象メソッドのifに入れてください。

利点: - スイッチのインテリジェンスは、スイッチが所属するクラス内にあります。 - 新しいタイプが追加されると、このタイプを新しいタイプに追加するためにコンパイラエラーが発生します。

1

私は、一連の 'if'句を実行する代わりに、継承を使用して必要なものを達成することを提案します。最初に、基本クラスに仮想メソッドを作成します。私はtodolistのオブジェクトがIListのであると仮定すると、ちょうどそれを変更しています(そして、あなたは子クラスのメソッドを作成

public class Task 
{ 
    (...) 
    public virtual void ShowEditForm(IList todoList); 
    (...) 
} 

:仮想メソッドでは、それは、基底クラスでのみ宣言を任意の実装を持っていないことを意味しますそうでない場合)。

public class Note: Task 
{ 
    (...) 
    public override void ShowEditForm(IList todoList) 
    { 
     (new noteBuilder(taskToEdit)).Show(); 
    } 
    (...) 
} 

public class Reminder: Task 
{ 
    (...) 
    public override void ShowEditForm(IList todoList) 
    { 
     (new reminderBuilder(taskToEdit)).Show(); 
    } 
    (...) 
} 

私はすべてのクラスを書きませんでしたが、あなたはそのアイデアを持っていると思います。メソッドを呼び出すには、あなただけのTaskクラスからメソッドを呼び出し、そして右の方法が実行されます:あなたは、タスクの新しいタイプを作成したい

int edi = taskNameBox.SelectedIndex; 
Task checkTask = todoList.ElementAt(edi); 
checkTask.ShowEditForm(todoList); 

この方法で、あなただけの子クラスを作成する必要があります適切な方法で、継承システムは残りを行います。

子メソッド宣言のoverrideキーワードは重要です。これは、このメソッドがBaseClassから呼び出されたとしても呼び出されるべきであることをコンパイラーに通知するためです。

+0

非常に良いアプローチ! – nawfal

+0

私の知らないことは申し訳ありませんが、IListとList の違いは何ですか? – WillzSawyer

+0

IListは、リスト、ArrayList、SortedListなどのほとんどの種類のコレクションへのインターフェイスです。 List はListオブジェクトです。しかし、この例では、オブジェクトの実際の型を使用するのが最善の方法ですが、例では型が特定されていないため、IListを配置しました。 – Marlon

1

最初に、2番目のメモに。あなたが話していることは、すべてのフォームが親で参照するグローバルオブジェクトを持つことです。それはうまくいきますが、フォームが変更されたときにすべてのフォームが同期されていることを確認するメカニズムがあることを確認する必要があります。私は必ずしもそれを主張しているわけではありませんが、それを考えるときは注意の言葉を追加するだけです:)

投稿コードに関しては、これをStrategy Patternの方法に変える方がいいでしょう。ベースクラス/インタフェースで、Showメソッドを持ちます。それから、checkTask.Show(todoList);に電話するだけです。あなたはTaskから来ることをしたくない場合は、すべてが上記ベースから継承フォームを持っている可能性があり、あなたは単にform.Show();

1
を呼び出した上で、適切なフォームを Tasklist取り込んで返し​​を使用することができますこのような

コードは、おそらくそう(Taskは、.NETに含まれる1つされていないと仮定)のように、これを抽象化したほうが良いです、維持することは困難である:

public interface IBuilder 
{ 
    void Show(); 
} 

public abstract class Task 
{ 
    // ... 
    public abstract IBuilder GetBuilder(TaskList todoList); 
    // ... 
} 

public class Note : Task 
{ 
    public override IBuilder GetBuilder(TaskList todoList) 
    { 
     return new noteBuilder(todoList); 
    } 
    // ... 
} 

// etc. 

private void itemEdit_Click(object sender, EventArgs e) 
{ 
    int edi = taskNameBox.SelectedIndex; 
    Task checkTask = todoList.ElementAt(edi); 

    IBuilder builder = checkTask.GetBuilder(todoList); 
    builder.Show(); 
} 

代わりに、あなたは、噴射パターンを使用することができます

public abstract class Task 
{ 
    protected Task(Func<TaskList, IBuilder> builderStrategy) 
    { 
     _builderStrategy = builderStrategy; 
    } 

    public IBuilder GetBuilder(TaskList todoList)) 
    { 
     return _builderStrategy(todolist); 
    } 
} 

public class Note : Task 
{ 
    public Note(Func<TaskList, IBuilder> builderStrategy) : base(builderStrategy) {} 
} 

// ... 
note = new Note(x => return new noteBuilder(x)); 
+0

申し訳ありませんが、私は抽象クラスの概念を本当に理解しているのか分かりません。私は、抽象クラスのオブジェクトを作成することができないと私が教えてきたことから印象を受けました。私たちはこれを教えている可能性がありますが、私たちは複雑さに苦しんでいません。 – WillzSawyer

+0

いいえ、抽象クラスのインスタンスを作成することはできませんが、おそらくそれを継承するクラスのインスタンスを作成することになります。ここでのアイデアは、ビルダーを作成する責任をクラスに移すことです。したがって、あなたの質問にあなたが説明した長いif..elseチェーンを持つ必要はありません。 –

+0

さて、私はベースクラスのリストを作成しているので、ベースクラスオブジェクトのリストを作成しています。または、リストの仕組みを誤解していて、実際に基底クラスから継承するオブジェクトを保持する構造を作成していますか? – WillzSawyer

関連する問題