Home > OS >  Using a case statement while creating a list
Using a case statement while creating a list

Time:12-20

I have a list which is a bunch of functions as displayed below

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

I have to add another function to the list based on a condition.

int result = select something from 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
}

I am trying to avoid creating 2 different sets for a simple if condition like below

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
}

Is there a way to implement this condition within the list creation?

CodePudding user response:

I think it would be very readable if you can add a new kind of step - "do nothing":

// 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
}

Then, you can use a simple ternary operator:

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

It would be even more readable if you can make factory methods for all your steps, so that you don't have the word new all the time.

You can also use a switch expression:

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

which would be very useful if you have more complicated decisions to make.

If the number of steps in the list of steps is important, you can always just remove the DoNothing steps from the list with a Where when you check the count.

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

CodePudding user response:

I suppose that StepList is a class which causes some operation to be performed when its object is encountered. The problem you are facing is that, depending on external condition, one StepList object should be added or not, and that complicates List initialization, right?

If that is the issue, then you may introduce a special "do nothing" StepList subclass, e.g. called Empty. Your list initialization would then look like this:

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
}

With this design, your list will always have the same number of items, but the result of their execution would depend on external condition.

CodePudding user response:

I would use a method with IEnumerable as return type and do yield returns where necessary.

eg.

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);
   ...
}

and than intialize the list like this:

var listOfSteps = GetSteps().ToList();

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

CodePudding user response:

Collection initializers are just syntactic sugar. Example:

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;

This means that you can simply add this new item conditionally afterwards:

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