2012-03-30 3 views
0

私はこのような方法でクラス "タスク"のリストを作成しています。基本クラスのリスト<T>から子クラスのメソッドにアクセスできません。

List<Task> toDoList = new List<Task>; 

タスクは、基本クラスであり、そのように設計されています:

public class Task : IDetail 
{ 
    string _taskName;   //Task title. 
    string _taskDescription;  //Task description. 

    public Task(string tn, string td) //Constructor. 
    { 
     _taskName = tn; 
     _taskDescription = td; 
    } 

    // Method set or return _taskName. 
    public string taskName 
    { 
     get 
     { 
      return _taskName; 
     } 

     set 
     { 
      _taskName = value; 
     } 
    } 

    //Method to set or return _taskDescription. 
    public string taskDescription 
    { 
     get 
     { 
      return _taskDescription; 
     } 

     set 
     { 
      _taskDescription = value; 
     } 
    } 

    public virtual void editList() 
    { 
     Creator editCreator = new Creator(); 
     editCreator.Show(); 
    } 


} 

を何私はTODOをしようとしてきたことは、私が指名を持っている1のような継承されたクラス内に存在するコール方式」であります以下のように定義している。

class Note : Task, IDetail 
{ 
    string _noteDescription; 

    public Note(string nd, string tn, string td) //Constructor. 
     : base(tn, td) 
    { 
     _noteDescription = nd; 
    } 

    //Method to set or return _noteDescription. 
    public string noteDescription 
    { 
     get 
     { 
      return _noteDescription; 
     } 

     set 
     { 
      _noteDescription = value; 
     } 
    } 

    public override void editList() 
    { 
     noteBuilder editNote = new noteBuilder(); 
     editNote.Show(); 
    } 
} 

ただし、リスト上の継承されたタスクのメソッドを呼び出そうとすると、エラーが発生します。私はそのような方法にアクセスしようとしています:

toDoList.ElementAt(x).noteDescription; 

私の質問はどのようにエラーが発生するのを防ぐのですか?

エラー状態

「toDoList.Task」「noteDescription」と拡張子なしの方法などなど

は、私はおそらく抽象として基本クラスを宣言するれるべきの定義が含まれていませんか?または何か他に私が行方不明ですか?あなたがList<Task>を持って事前

+2

しかし、これは 'Task'のリストであり、そのサブクラス' Note'のリストではありません。なぜあなたは 'Note'のプロパティにアクセスすることができると期待していますか?リストに 'Task'のインスタンスが含まれていて、' Note'のインスタンスではない場合はどうなりますか? –

答えて

7

感謝します。それはのいずれかの種類のTaskのリファレンスを含む可能性があります。 異なる派生型であり、Noteではありません。 (それはすべてのタイプセーフであることができるように)、またはあなたがNoteにリストの要素をキャストする必要がありますどちらかしたいList<Note>

Note note = (Note) toDoList[x]; 
string description = note.noteDescription; 

(あなたがList<T>持っていることを考えると、あなたはElementAtを使用する必要はありません - インデクサーを使用)

+0

ありがとう、非常に有用:)私はあなたがそれがArrayだったようなリストに対処できるか分からなかった:) – WillzSawyer

0

あなたのリストはTaskオブジェクトではなく、Noteオブジェクトのリストであるため。。

Noteクラスのメソッドを呼び出す前に、オブジェクトをNoteオブジェクトにキャストする必要があります。

(toDoList.ElementAt(x) as Note).noteDescription; 

または

toDoList.Cast<Note>().ElementAt(x).noteDescription; 

2番目のオプションは、リスト内のすべてのオブジェクトがNoteオブジェクトで必要です。

1

フィルターリストと同様に、ノートに変換:

var noteList = toDoList.Where(x => x is Note) 
         .Select(x => (Note)x) 
         .ToList(); 

が、その後

noteList.ElementAt(x).noteDescription; 
0

notDescriptionを書くには、あなたの派生クラスのあなたが持っているプロパティです。しかし、ここであなたは、基本クラスに派生クラスのプロパティを取得することはできませんあなたのベースクラス

List<Task> toDoList = new List<Task>; 

のリストを作成しています。 ITはそれとは逆です。子クラスの基本クラスのプロパティにアクセスできます。

0

toDoListは、Note要素ではなく、Task要素を含みます。今度はNote要素はTask要素の型ですが、多態性は一方向でしか機能しません。サブクラスをそのスーパークラスのように扱うことはできますが、スーパークラスをサブクラスのように扱うことはできません。

あなたはそれについて考えるなら、あなたはそれがそのようにしなければならないことを認識します。 Fooと呼ばれる2番目のサブクラスTaskを持っていた場合:toDoListに入力することができます。FooのオブジェクトのnoteDescriptionにアクセスしようとすると、問題が発生します。

しかし、あなたが欲しいものを行う方法があるが、それだけのキャストが必要です。それを行うには

var note = toDoList.ElementAt(x) as Note; 
var noteDescription = note==null ? "<not a note>" : note.noteDescription; 

他の方法で、当然のことながら、どこでだろう、TodonoteDescriptionを移動するだろうTodoのどのサブクラスからでもアクセスできますが、それは名前がNoteに属していることを意味するため、おそらくあなたが望むものではありません。

関連する問題