2012-03-30 46 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(); 
    } 


} 

我一直在试图待办事项是调用方法继承的类中存在像一个一个我候“注意“并且已经将其定义如下。

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”,没有扩展方法等等等等

我应该算得上宣布的基类为抽象的定义?还是有什么我失踪?

很多感谢

+2

但它'Task',而不是它的子类'Note'的名单列表。你为什么期望它允许你访问'Note'的属性?如果列表中包含的是*不是Note'的'*实例Task'的'实例? – 2012-03-30 21:52:37

回答

7

你已经有了一个List<Task>。这可能包含任何种类的Task参考 - 例如一个不同派生类型,而不是Note要么你想List<Note>(所以它可以全部是类型安全的),或者你需要在列表的元素转换为Note

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

(既然你已经有了一个List<T>,您不需要使用ElementAt - 使用索引器。)

+0

谢谢,非常有帮助:)我不知道你能对付列表,就像是一个数组:) – WillzSawyer 2012-03-30 22:23:32

0

因为您的列表是Task对象列表,而不是Note对象。

在调用Note类的方法之前,您需要将对象转换为Note对象。

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

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

第二个选项需要在列表中的所有对象必须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包含Task元素,而不是Note元素。现在Note元素是一种Task元素,肯定的,但多态性只在一个方向的工作原理:你可以把一个子类,像它的父类,但不能像对待一个子类的超没有第一投射它。

如果你仔细想想,你会认识到它必须是这样。如果你有第二个子类TaskFoo:你可以把这两种类型放在toDoList ......如果你试图访问noteDescription类型为Foo的对象,你会遇到麻烦。

然而,有一种方法可以做你想做的,它只是需要投:

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

的另一种方式做到这一点,当然,将是移动noteDescriptionTodo,哪里会是从Todo任何子类访问,但是这可能不是你想要的,因为顾名思义,它属于Note