无法从List<;T>;基类的

本文关键字:基类 gt lt List | 更新日期: 2023-09-27 18:29:38

我正在以这样的方式创建一个类"Task"的列表。

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吗?还是我还缺少什么?

提前感谢

无法从List<;T>;基类的

您有一个List<Task>。它可以包含任何类型的Task引用,例如不同的派生类型,而不是Note要么您想要一个List<Note>(这样它都可以是类型安全的),要么您需要将列表的元素强制转换为Note:

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

(假设您有一个List<T>,则不需要使用ElementAt-使用索引器。)

过滤列表并将其转换为注释,如:

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

然后写入

noteList.ElementAt(x).noteDescription;
因为您的列表是Task对象的列表,而不是Note对象的列表。

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

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

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

第二个选项要求列表中的所有对象都是Note对象。

notDescription是派生类的属性。但在这里,您正在创建一个基本类的列表

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

不能在基类中获取派生类的属性。IT的工作方式正好相反。您可以访问子类中基类的属性。

toDoList包含Task元素,而不是Note元素。现在,Note元素当然是Task元素的一种类型,但多态性只在一个方向上起作用:可以像对待超类一样对待子类,但如果不首先强制转换,就不能像对待子类一样对待超类。

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

然而,有一种方法可以做你想做的事,它只需要一个演员阵容:

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

当然,另一种方法是将noteDescription移动到Todo中,在那里可以从Todo的任何子类访问它,但这可能不是你想要的,因为这个名称意味着它属于Note