【问题标题】:Using a case statement while creating a list在创建列表时使用 case 语句
【发布时间】:2022-01-22 00:32:03
【问题描述】:

我有一个列表,其中包含如下所示的一堆函数

var listOfSteps = new List<StepList>
{
  new Setup(parameters),
  new InitializeClass(parameters),
  new calculate(parameters),
  //72 steps in total
}

我必须根据条件向列表中添加另一个函数。

int result = 从 someTable 中选择一些东西

var listOfSteps = new List<StepList>
{
  new Setup(parameters),
  new InitializeClass(parameters),
  new calculate(parameters),
  if (result = 5) {new display(parameters)},   //This is the additional step to be added
  //72 steps in total
}

我试图避免为如下所示的简单 if 条件创建 2 个不同的集合

if(result = 5)
{
  var listOfSteps = new List<StepList>  //list with the new function
  {
    new Setup(parameters),
    new InitializeClass(parameters),
    new calculate(parameters),
    new display(parameters),
    //72 steps in total
  }
}
else
{   //list without the new function
    new Setup(parameters),
    new InitializeClass(parameters),
    new calculate(parameters),
    //72 steps in total
}

有没有办法在列表创建中实现这个条件?

【问题讨论】:

  • 为什么不把 if 放在 display() 或者另一个调用 display 的函数中?
  • 不在初始化程序中,但是是什么阻止您在初始化程序之后添加条件?
  • var listOfSteps = new List&lt;StepList&gt; { ... }; if (result == 5) { listOfSteps.Add(...); } -> 我没有看到其中的问题或复杂性

标签: c# .net


【解决方案1】:

集合初始化器只是语法糖。示例:

var ints = new List<int> { 1, 2, 3 };

// is equivalent to

var temp = new List<int>();
temp.Add(1);
temp.Add(2);
temp.Add(3);
var ints = temp;

这意味着您可以在之后有条件地简单地添加这个新项目:

var listOfSteps = new List<StepList>
{
  new Setup(parameters),
  new InitializeClass(parameters),
  new calculate(parameters),
  ...
}
if (result == 5) {
    listOfSteps.Add(new display(parameters));
}

【讨论】:

  • 是的,这是我实现的,因为其他解决方案都不适合我。但是我无法在初始化后调用 listOfSteps.Add() ,因为函数的顺序非常重要。因此,我只是在初始化期间将其添加到列表中,并在初始化后根据条件删除了该步骤。 var displayObj = 新显示(参数); var listOfSteps = new List { new Setup(parameters), new InitializeClass(parameters), displayObj, //所有其​​他函数 } if (result != 5) { listOfSteps.Remove(displayObj); }
【解决方案2】:

我认为如果您可以添加一种新的步骤-“什么都不做”,那将非常可读:

// shouldn't StepList be renamed to "Step"?
class DoNothing: StepList {
    ...

    // implement this so that when the list of steps is processed,
    // this will do nothing
}

然后,你可以使用一个简单的三元运算符:

var listOfSteps = new List<StepList>
{
  new Setup(parameters),
  new InitializeClass(parameters),
  new calculate(parameters),
  result == 5 ? 
      new display(parameters)
      : 
      new DoNothing(),
}

如果您可以为所有步骤创建工厂方法,那将更具可读性,这样您就不会一直使用new 这个词。

你也可以使用 switch 表达式:

var listOfSteps = new List<StepList>
{
  new Setup(parameters),
  new InitializeClass(parameters),
  new calculate(parameters),
  result switch { 
      5 => new display(parameters),
      _ => new DoNothing(),
  }
}

如果您要做出更复杂的决定,这将非常有用。

如果步骤列表中的步骤数很重要,您始终可以在检查计数时使用Where 从列表中删除DoNothing 步骤。

listOfSteps.Where(step => step is not DoNothing).Count()

【讨论】:

  • 这对我不起作用,因为该列表与 UI 耦合,并且会将 DoNothing() 显示为我试图避免的步骤之一。
  • @Jagath 正如我最后所说,DoNothing 步骤可以很容易地删除。或者您的 UI 可以被编码为明确不显示它们(在这种情况下,Empty 可能是一个更好的名称)。
  • 是的,初始化后删除DoNothing()函数就可以了。
【解决方案3】:

我想StepList 是一个类,当遇到它的对象时会导致执行一些操作。您面临的问题是,根据外部条件,是否应该添加一个StepList 对象,这会使List 初始化复杂化,对吧?

如果这是问题所在,那么您可以引入一个特殊的“什么都不做”StepList 子类,例如叫Empty。您的列表初始化将如下所示:

var listOfSteps = new List<StepList>
{
    new Setup(parameters),
    new InitializeClass(parameters),
    new calculate(parameters),
    (result == 5 ? new display(parameters) : new Empty())
    // ... 72 steps in total
}

使用这种设计,您的列表将始终具有相同数量的项目,但它们的执行结果将取决于外部条件。

【讨论】:

  • 这是有道理的。因此,当结果为 5 时,我会假设我的变量 listOfSteps 将包含 display(parameters) 作为值之一。但是当它不正确时,是否会将 Empty() 作为值之一添加(即使它什么都不做)
  • @Jagath 就是这样。这个对象什么都不做,也没有 UI 表示。
  • 我收到一个错误“Empty is inaccessible due to its protection level”,即使我没有定义它。默认是私有的吗?在我的函数中调用它之前我应该​​进行任何更改吗?
【解决方案4】:

我会使用IEnumerable 作为返回类型的方法,并在必要时使用yield returns。

例如。

private IEnumerable<StepList> GetSteps()
{
   yield return new Setup(parameters);
   yield return new InitializeClass(parameters);
   yield return new calculate(parameters);
   if (result = 5) yield return new display(parameters);
   ...
}

然后像这样初始化列表:

var listOfSteps = GetSteps().ToList();

https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/yield

【讨论】:

    猜你喜欢
    • 2019-06-22
    • 2019-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-24
    • 2012-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多