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();
}
精彩评论