无法从基类的List <t>访问子类的方法。</t>

时间:2012-03-30 21:49:03

标签: c#

我正在以这样的方式创建一个“任务”类列表。

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吗?或者还有其他我想念的东西?

非常感谢提前

5 个答案:

答案 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}}。