如果使用继承,如何检查列表的类型

时间:2012-03-29 13:31:12

标签: c# winforms

我目前正在开发一个C#程序,它创建一个List,对象为Task,对象Task是一个基类,还有很多其他的继承。我想要的是比较所述列表中的一个对象的类型,以查看应该打开哪个表单以进行编辑。

这是我已经创建的代码。

private void itemEdit_Click(object sender, EventArgs e)
    {
        int edi = taskNameBox.SelectedIndex;
        Task checkTask = todoList.ElementAt(edi);

        if(checkTask.GetType is Note)
        {
            noteBuilder editNote = new noteBuilder(todoList);
            editNote.Show();
        }

        else if(checkTask.GetType is extendedTask)
        {
            extendedTaskBuilder editTask = new extendedTaskBuilder(todoList);
            editTask.Show();
        }

        else if(checkTask.GetType is Reminder)
        {
            reminderBuilder editReminder = new reminderBuilder(todoList);
            editReminder.Show();
        }

        else if (checkTask.GetType is Appointment)
        {
            appointmentBuilder editAppointment = new appointmentBuilder(todoList);
            editAppointment.Show();
        }
    }

在次要注释中,如果不是在表单之间传递列表并生成表单的新对象,而是显示信息,而不是在表单之间传递单个对象,而只是每次新元素时更新表单,这样会更容易被添加到列表中。

非常感谢

5 个答案:

答案 0 :(得分:1)

您是否尝试过这样检查:

if (checkTask is Note)
{

}
...

答案 1 :(得分:1)

您是否考虑为现在切换的所有类型创建基类并调用虚拟(抽象)方法?

现在将所有代码放在if覆盖的抽象方法中。

优点: - 交换机的智能属于它所属的类。 - 添加新类型时,您会收到编译器错误,并将此功能添加到新类型中。

答案 2 :(得分:1)

我建议你不要使用那些'if'子句,而是使用继承来实现你需要的东西。首先,在基类中创建一个虚方法。虚方法意味着它不会在基类中有任何实现,只有声明:

public class Task
{
    (...)
    public virtual void ShowEditForm(IList todoList);
    (...)
}

然后你创建子类方法(我假设todoList对象是一个IList,但只是改变它,如果不是)。

public class Note: Task
{
    (...)
    public override void ShowEditForm(IList todoList)
    {
        (new noteBuilder(taskToEdit)).Show();
    }
    (...)
}

public class Reminder: Task
{
    (...)
    public override void ShowEditForm(IList todoList)
    {
        (new reminderBuilder(taskToEdit)).Show();
    }
    (...)
}

我没有写所有课程,但我认为你已经有了这个想法。要调用该方法,只需从Task类中调用该方法,然后执行正确的方法:

int edi = taskNameBox.SelectedIndex;
Task checkTask = todoList.ElementAt(edi);
checkTask.ShowEditForm(todoList);

这样,当你想创建新类型的Task时,你只需要用正确的方法创建子类,继承系统将完成其余的工作。

另外一点,子方法声明中的override关键字很重要,因为它告诉编译器即使从BaseClass调用它也应该调用此方法。

答案 3 :(得分:1)

首先,到你的第二个音符。你所谈论的是拥有一个全局对象,所有表单都在某些父对象中引用。这可以工作,但是您需要确保有一些机制可以确保所有表单在更改时同步,这可能会变得混乱并且有点乱。我不一定主张反对它,但只是在考虑它时加上谨慎的话语:)

对于您发布的代码,最好将其转换为Strategy Pattern方法,其中所有表单都从具有Show方法的基类/接口继承。然后,您需要做的就是致电checkTask.Show(todoList);。如果您不希望来自Task,那么您的表单可以从上面的基础继承,您可以使用Task和{{1} list然后返回您只需调用form.Show();

的相应表单

答案 4 :(得分:1)

像这样的代码很难维护,你最好抽象出来,就像这样(假设Task不是.net中包含的那个):

public interface IBuilder
{
     void Show();
}

public abstract class Task
{
    // ...
    public abstract IBuilder GetBuilder(TaskList todoList);
    // ...
}

public class Note : Task
{
    public override IBuilder GetBuilder(TaskList todoList)
    {
        return new noteBuilder(todoList);
    }
    // ...
}

// etc.

private void itemEdit_Click(object sender, EventArgs e)
{
    int edi = taskNameBox.SelectedIndex;
    Task checkTask = todoList.ElementAt(edi);

    IBuilder builder = checkTask.GetBuilder(todoList);
    builder.Show();
}

或者,您可以使用注射模式:

public abstract class Task
{
    protected Task(Func<TaskList, IBuilder> builderStrategy)
    {
        _builderStrategy = builderStrategy;
    }

    public IBuilder GetBuilder(TaskList todoList))
    {
        return _builderStrategy(todolist);
    }
}

public class Note : Task
{
    public Note(Func<TaskList, IBuilder> builderStrategy) : base(builderStrategy) {}
}

// ...
note = new Note(x => return new noteBuilder(x));