2011-04-21 33 views
0

我想实现只是为了好玩自定义开关的情况下..问题在实现我自己的开关类

的做法是,我已经创建了一个继承Dictionary对象

public class MySwitch<T> : Dictionary<string, Func<T>> 
    { 
     public T Execute(string key) 
     { 
      if (this.ContainsKey(key)) return this[key](); 
      else return default(T); 
     } 
    } 

和A类我使用的是下

new MySwitch<int> 
    { 
    { "case 1", ()=> MessageBox.Show("From1") }, 
    { "case 2..10", ()=>MessageBox.Show("From 2 to 10") },    
    }.Execute("case 2..10"); 

但是,如果我指定“案2”它给出了一个默认值,关键是不是在字典。

使得的全部目的“情况下2..10”是,如果用户输入什么之间的情况下为2〜10的情况下,它会执行相同的值。

任何人都可以请帮我解决这个问题吗?

感谢

回答

1

字符串“案2..10”存储在字典对象和必由之路包含键返回TURE是,如果你恰好提供该字符串。这意味着您必须将确切的字符串“case 2..10”传递给containskey才能返回true。

0

我的adice是看规格模式。

您可以让每个函数附加一个或多个规范,然后执行相关函数(或者如果需要的话)。

简而言之:

public interface ISpecification<T> 
{ 
    bool IsSatisfiedBy(T item); 
} 

和特定的实现:

public class IntegerRangeSpecification : ISpecification<int> 
{ 
    private readonly int min; 
    private readonly int max; 

    public IntegerRangeSpecification(int min, int max) 
    { 
     this.min = min; 
     this.max = max; 
    } 
    public bool IsSatisfiedBy(int item) 
    { 
     return (item >= min) && (item <= max); 
    } 
} 

当然,你宁愿RangeSpecification<T> : ISpecification<T>但需要一些更多的努力/设计(如where T : IComparable)。

无论如何,我希望能让你走上正轨。

0

首先你可能想要封装一个字典,而不是扩展字典,因为我怀疑你需要在你的switch类中的字典的所有方法。

其次,您需要分离您的案例字符串,并将自己的密钥添加到字典中。使用字符串作为键的方法让我觉得不是最好的想法。通过使用字符串作为您的密钥,您要求密钥完全匹配。如果你使你的字典使用整数键,并且你改变了它的初始化方式。与交换机的精神一致,你可以做这样的事情:

public class Switch<T> 
{ 
    private Dictionary<int, Func<T>> _switch = new Dictionary<int, Func<T>>(); 
    private Func<T> _defaultFunc; 

    public Switch(Func<T> defaultFunc) 
    { 
     _defaultFunc = defaultFunc; 
    } 


    public void AddCase(Func<T> func, params int[] cases) 
    { 
     foreach (int caseID in cases) 
     { 
      _switch[caseID] = func; 
     } 
    } 

    public void AddCase(int beginRange, int endRange, Func<T> func) 
    { 
     for (int i = beginRange; i <= endRange; i++) 
     { 
      _switch[i] = func; 
     } 
    } 

    public T Execute(int caseID) 
    { 
     Func<T> func; 
     if(_switch.TryGetValue(caseID, out func)){ 
      return func(); 
     }else{ 
      return _defaultFunc(); 
     } 
    } 
} 

哪位能像这样被使用:

Switch<int> mySwitch = new Switch<int>(() => {Console.WriteLine("Default"); return 0;}); 
mySwitch.AddCase(() => { Console.WriteLine("1"); return 1; }, 1); 
mySwitch.AddCase(2, 10,() => { Console.WriteLine("2 through 10"); return 1; }); 

mySwitch.AddCase(() => { Console.WriteLine("11, 15, 17"); return 2; }, 11, 15, 17); 

mySwitch.Execute(1); 
mySwitch.Execute(2); 
mySwitch.Execute(3); 
mySwitch.Execute(4); 
mySwitch.Execute(11); 
mySwitch.Execute(12); 
mySwitch.Execute(15); 

还有一堆的,你可以完成你想要的方式不同。希望这有助于一些