如何处理具有不同参数的派生 类

How to handle derived classes featuring different parameters

我是 C# 的新手,我有一个项目,其中我有一个父 class Task 派生 classes FixedTaskRelativeTask .

FixedTaskRelativeTask 具有不同的属性,命名也不同。我需要对每个 Task 执行一些计算来计算一些工作量。

A Project 包含不同的 Tasks,可以是各种类型,例如FixedTaskRelativeTask。我正计划做这样的事情:

foreach (Task Task in this.Tasks)
{
    switch (Task)
    {
        case FixedTask:
            switch (Task.Frequency)
            {
                case "Daily":
                    // do some calculations
                 
                // other frequency cases
            }
        // other Task cases
    }

但是我收到一个错误,提示 Task 没有特定参数,因为它在 FixedTask 中实现,但在 RelativeTask 中没有实现。

虽然 switch 模式允许 C# 理解他必须考虑的类型,但显然不是。

实现我想要的目标的正确方法是什么?

你需要告诉编译器Task实际上是一个FixedTask。

....

   case FixedTask:
        switch (((FixedTask)Task).Frequency)
        {
            case "Daily":
....

这会将 Task 转换为 FixedTask,还有其他几种方法可以实现同样的效果 - 请查看 https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/types/casting-and-type-conversions,其中提供了更多详细信息

模式匹配:case FixedTask f.

但你不应该。你的基础 class 不应该知道也不关心派生的 classes 是如何实现的。

OO 和继承的目的是派生的 classes 包含它们自己的逻辑。因此,如果您的任务运行器想要执行任务,请这样做:

foreach (Task task in this.Tasks)
{
    task.Execute();
}

然后每个任务派生 class 在其覆盖的 Execute() 方法中都有逻辑。

模式匹配帮助:

foreach (Task Task in this.Tasks)
        {
            switch (Task)
            {
                case FixedTask ft:
                    switch (ft.Frequency)
                    {
                        case "Daily":
                        ...
                    }
                case RelativeTask rt:
                    switch (rt.OtherProperty)
                    {
                        case ...:
                    }

作为快速(但不是最佳)修正,我建议模式匹配,即

foreach (Task task in Tasks) {
  if (task is FixedTask fixedTask) {
    // From now on you work with fixedTask
    switch (fixedTask.Frequency) {
      ...
    }
  } 
  else if (task is RelativeTask relativeTask) {
    // From now on you work with relativeTask
  } 
}