我正在以这样的方式创建一个“任务”类列表。
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();
}
}
我一直在尝试的是调用方法,这些方法存在于继承的类中,就像我指定的“Note”一样,并将其定义如下。
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'的定义,也没有扩展方法等等。
我应该将基类声明为Abstract吗?或者还有其他我想念的东西?
非常感谢提前
答案 0 :(得分:7)
你有List<Task>
。这可能包含任何类型的Task
引用 - 例如一个不同的派生类型,而不是Note
。 要么你想要一个List<Note>
(所以它都可以是类型安全的),或者你需要将列表的元素强制转换为Note
:
Note note = (Note) toDoList[x];
string description = note.noteDescription;
(鉴于你有一个List<T>
,你不需要使用ElementAt
- 使用索引器。)
答案 1 :(得分:1)
过滤列表并将其转换为注释,例如:
var noteList = toDoList.Where(x => x is Note)
.Select(x => (Note)x)
.ToList();
然后写
noteList.ElementAt(x).noteDescription;
答案 2 :(得分:0)
因为您的列表是Task
个对象的列表,而不是Note
个对象。
在调用Note
类的方法之前,您需要将对象强制转换为Note
个对象。
(toDoList.ElementAt(x) as Note).noteDescription;
或
toDoList.Cast<Note>().ElementAt(x).noteDescription;
第二个选项要求列表中的所有对象都是Note
个对象。
答案 3 :(得分:0)
notDescription是您的派生类的属性。但是在这里你要创建一个基类列表
List<Task> toDoList = new List<Task>;
您无法在基类中获取派生类的属性。 IT以另一种方式工作。您可以在子类中访问基类的属性。
答案 4 :(得分:0)
toDoList
包含Task
个元素,而不是Note
个元素。现在Note
元素是一种Task
元素,但是,多态只能在一个方向上工作:你可以像处理它的超类一样处理子类,但是你不能把超类视为子类首先施展它。
如果你仔细想想,你会发现它必须是这样的。如果您有Task
的第二个子类Foo
怎么办?如果您尝试访问toDoList
上的noteDescription
,则可以将这两种类型放在Foo
中属于var note = toDoList.ElementAt(x) as Note;
var noteDescription = note==null ? "<not a note>" : note.noteDescription;
类型,你遇到了麻烦。
然而,有一种方法可以做你想要的,它只需要一个演员:
noteDescription
当然,另一种方法是将Todo
移到Todo
,可以从Note
的任何子类访问{{1}},但这可能不是你的意思希望,因为该名称暗示它属于{{1}}。