views:

52

answers:

3

I have the following enum ( pseudo code )

enum RunSequence : int 
{
ABCD = 1 , 
BCDA = 2 , 
DABC = 3 , 
....
}

You get the idea ... Now if each letter represents some 4 lines of code , what would be the smartest way of building the logic for running those 16 lines of code in the desired sequence according to the RunSequence passed

Am I totally lost ... should this be achieved via totally different approach ? I d rather not use goto but some OO approach ... design pattern

A: 

Each 4 line chunk of code should be in it's own method. Something like

ExecuteCode_A(){/*...*/}

Then you can create a Delegate with no parameters called CodeExecutor. Instantiate an instance of the delegate for each block of code pointing to the correct method. Pass an array loaded with the delegate instances in the correct order (or list, or something) into your main function. Iterate through it, invoking each delegate.


There is another similar method. Create an Interface called ICodeBlockRunner which defines a method called Run(). For each unique code block, create a class that implements the interface and implement the Run() method to execute the 4 lines of code. Then your function would accept an Array (or something Enumerable) of ICodeBlockRunners (instantiated classes that implement ICodeBlockrunner of course) in the desired order. You'd iterate over the values and call Run() on each ICodeBlockRunner.

colithium
A: 
private static Dictionary<char, Action> funcDic = new Dictionary<char, Action>{
{ 'A', funcA }, { 'B', funcB }, { 'C', funcC }, { 'D', funcD } };

public static void Run(RunSequence sequence){
    foreach (char c in Enum.GetName(typeof(RunSequence), sequence))
        funcDic[c]();
}

Where funcA..funcD are the methods containing the code snippets. If you need to pass parameters between the code snippets, place them in a container class and use Action<ContainerClass> instead of Action<>.

Marcus Andrén
A: 

Did you guys mean something like this ?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ColorsUtility
{
    public abstract class Runner 
    {

     public abstract void Run (string param );
    }

    class ARunner : Runner , ICodeBlockRunner
    {
     public override void Run( string param)
     {
      Console.WriteLine("ARunner Run () ");
     } //eof method 
    } //eof class 

    class BRunner :Runner ,  ICodeBlockRunner
    {
     public override void Run(string param)
     {
      Console.WriteLine("BRunner Run () ");
     } //eof method 
    } //eof class 

    class CRunner : Runner , ICodeBlockRunner
    {
     public override void Run( string param)
     {
      Console.WriteLine("CRunner Run () ");
     } //eof method 
    } //eof class 

    class PermutationRunner
    {

     public PermutationRunner()
     {
      throw new Exception("Need integer for setting the running sequence");

     }

     public PermutationRunner(EnuExecSetter enu)
     {
      this.PopulateRunners(enu);

     }

     private static readonly log4net.ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
     public enum EnuExecSetter
     {
      ABC = 1,
      ACB = 2,
      BCA = 3,
      BAC = 4,
      CAB = 5,
      CBA = 6
     } //eof enum 

     static void Main(string[] args)
     {
      string param = "theParam";

      foreach (int val in Enum.GetValues(typeof(EnuExecSetter)))
      {
       Console.WriteLine("Volume Value: {0}\n Member: {1}",
       val, Enum.GetName(typeof(EnuExecSetter), val));
       PermutationRunner pr = new PermutationRunner((EnuExecSetter)val);
       pr.BigRun(param);
       Console.WriteLine("hit a key ");

       Console.ReadLine();


      }


     } //eof method 


     public List<Runner> Runners { get; set; }

     private void PopulateRunners(EnuExecSetter enu)
     {
      string param;
      List<Runner> runners = new List<Runner>();

      switch (enu)
      {
       case EnuExecSetter.ABC:
        runners.Add(new ARunner());
        runners.Add(new BRunner());
        runners.Add(new CRunner());
        break;
       case EnuExecSetter.ACB:
        runners.Add(new ARunner());
        runners.Add(new CRunner());
        runners.Add(new BRunner());
        break;
       case EnuExecSetter.BCA:
        runners.Add(new BRunner());
        runners.Add(new CRunner());
        runners.Add(new ARunner());
        break;
       case EnuExecSetter.BAC:
        runners.Add(new BRunner());
        runners.Add(new ARunner());
        runners.Add(new CRunner());
        break;
       case EnuExecSetter.CAB:
        runners.Add(new CRunner());
        runners.Add(new ARunner());
        runners.Add(new BRunner());
        break;
       case EnuExecSetter.CBA:
        runners.Add(new CRunner());
        runners.Add(new BRunner());
        runners.Add(new ARunner());
        break;
       default:
        runners.Add(new CRunner());
        runners.Add(new BRunner());
        runners.Add(new ARunner());
        break;

      }
      this.Runners = runners;

     } //eof method 


     public void BigRun(string param)
     {
      foreach (Runner r in this.Runners)
      {
       r.Run(param);
      }
     }

    } //eof class 

public interface ICodeBlockRunner
{
 void Run(string param);

}

} //eof namespace
Sort of, but minus the enum, it seems awkward. I was thinking more of populating the list at runtime based off the UI or however you originally get the input. A Dictionary as mentioned above is a great idea if you want to take character inputs.
colithium