开发者

Duplicate key values in dictionary object and the wrong design

I wanted to do something ‘dynamic’ with a dictionary object and supplied command line arguments. The command line arguments are Boolean and I could then call methods if any one of them was true. So…

public class CommandLineArguments开发者_JAVA百科
{
    public bool AddSection1 { get; set; }
    public bool AddSection2 { get; set; }
    public bool Addsection3 { get; set; }        
}

class RunSomeActions
{
    private Dictionary<bool, Action> methodList = new Dictionary<bool, Action>();

    public RunSomeActions()
    {
        // create the switches as if from a command line
        CommandLineArguments parameters = new CommandLineArguments();
        parameters.AddSection1 = true;
        parameters.AddSection2 = false;
        parameters.Addsection3 = true;

        // setup the methods for the switches
        methodList.Add(parameters.AddSection1, this.Section1);
        methodList.Add(parameters.AddSection2, this.Section2);
        methodList.Add(parameters.Addsection3, this.Section3);

        foreach (var entry in methodList)
        {
            // if the switch is on
            // call the method
            if (entry.Key)
                methodList[entry.Key]();
        }


    }

    private void Section1()
    { 
        // add specific entries into a file
    }

    private void Section2()
    { 
        // perform analysis on a file
    }

    private void Section3()
    { 
        // delete everything and start again
    }

}

This works great if you only ever have two values of true and false, so it’s not much good really. What I did like about this approach was not having to parse the arguments manually and then build an Action list. Is there a way I can salvage this design?


Since you're not actually using the dictionary for lookups, but just for storage and iteration, instead of using a Dictionary<K,V>, you can just use a List<KeyValuePair<K,V>>.

The main difference from a code perspective would be changing .Add to:

methodList.Add(new KeyValuePair<bool, Action>(parameters.AddSection1, this.Section1));

Then, when you use, switch to:

foreach (var entry in methodList)
{
    // if the switch is on
    // call the method
    if (entry.Key)
        entry.Value(); // Execute "value" directly
}

That being said, you can take this one step further, potentially, and just store a List<Action> directly. Only add actions to the list where the condition is true, then execute them all.


I'd suggest creating a structure.

struct MethodListItem
{
    bool IsActive;
    Action Action;
}

Then declare methodList as (surprise) a List<MethodListItem>, and add like this:

methodList.Add(new MethodListItem { IsActive = parameters.AddSection1, Action = this.Section1});
methodList.Add(new MethodListItem { IsActive = parameters.AddSection2, Action = this.Section2});
methodList.Add(new MethodListItem { IsActive = parameters.Addsection3, Action = this.Section3});

The loop body then becomes the somewhat more readable:

foreach (var entry in methodList)
{
    // if the switch is on
    // call the method
    if (entry.IsActive) entry.Action();
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜