C# 使用动作字典而不是switch语句
我只是在回顾我的一些旧代码(有一些空闲时间),我注意到一个相当长的switch语句。由于获得了新的知识,我将其重构为以下形式:C# 使用动作字典而不是switch语句,c#,refactoring,polymorphism,conditional-statements,C#,Refactoring,Polymorphism,Conditional Statements,我只是在回顾我的一些旧代码(有一些空闲时间),我注意到一个相当长的switch语句。由于获得了新的知识,我将其重构为以下形式: private Dictionary<string, Action> createView { get { return new Dictionary<string, Action>() { {"Standard", Creat
private Dictionary<string, Action> createView
{
get
{
return new Dictionary<string, Action>()
{
{"Standard", CreateStudySummaryView},
{"By Group", CreateStudySummaryByGroupView},
{"By Group/Time", CreateViewGroupByHour}
};
}
}
private Dictionary createView
{
得到
{
返回新字典()
{
{“标准”,CreateStudySummaryView},
{“按组”,CreateStudySummaryByGroupView},
{“按组/时间”,CreateViewGroupByHour}
};
}
}
你会考虑这个好的练习吗?或者这仅仅是一个超常而不必要的例子?我热衷于确保我学到的新技术,不仅仅是为了它而变得聪明,而且它们确实为代码增加了好处
谢谢。长开关语句是一种典型的坏味道,并且总是重构的目标 此处要执行的“标准”步骤是。这是Martin Fowler的书(11年前出版于1999年)中列出的步骤之一 现在,把函数当作对象(比如动作)是如此容易,这可能是一个同样好的解决方案
不,我不认为你聪明是为了它。如果我想在将来添加另一个选项,我可以很容易地看到需要做什么 如果代码一经编写,基本上是静态的,不会有太多的更改,那么我就只能使用
开关了。至少从表面上看,您的字典方法有助于更具动态性——尽管这是基于需求的
至于用使用这种方法的代码替换任何地方的开关,我个人不会在大多数情况下这样做。我诚实的观点是,这只是为了它而变得聪明,但它仍然很容易维护。在我看来,个人品味高于最佳实践是这里最大的因素
另一方面,正如其他人所说,这可能是解决长switch语句的可行方案。同样,类似的东西也是支持行为更改的好方法。根据您的应用程序,您可以避免总是构造新的dictionary对象,但将其声明为类成员,在首次访问时初始化,并始终返回相同的实例。但很难说它是否真的适合你的需要。
我是说像这样
public class MyClass
{
Dictionary<string, Action> dict = null;
private Dictionary<string, Action> createView
{
get
{
if(dict == null)
{
dict = new Dictionary<string, Action>()
{
{"Standard", CreateStudySummaryView},
{"By Group", CreateStudySummaryByGroupView},
{"By Group/Time", CreateViewGroupByHour}
};
}
return dict;
}
}
}
公共类MyClass
{
字典dict=null;
专用字典createView
{
得到
{
if(dict==null)
{
dict=新字典()
{
{“标准”,CreateStudySummaryView},
{“按组”,CreateStudySummaryByGroupView},
{“按组/时间”,CreateViewGroupByHour}
};
}
返回命令;
}
}
}
编辑
从概念上看,用dictionaryTryGetValue
替换longswicth/case
是一个很好的解决方案
希望这有助于 这种方法非常好
我使用它不仅仅是操作
。它对过滤器和选择器也非常有效。比如:
var filters = new Dictionary<string, Func<MyEntity, bool>>()
{
// ...
};
var query = entities.Where(filters["X"]);
var filters=newdictionary()
{
// ...
};
var query=entities.Where(过滤器[“X”]);
+1谢谢你的链接,我以前从未见过重构目录——我会看一看。我原以为这不是我想要的答案,但想了想,确实如此。我有一个自动生成的文件,其中包含数千个开关案例,每个案例执行一个方法。它适用于Unity引擎的可序列化事件系统。现在,我有数千个类继承了一个抽象类,其中包含一个Invoke虚拟函数和一个字典,其中包含替换开关的抽象类。现在,调用方可以缓存从字典中获取的继承类并调用其虚拟函数,而不是每次调用都通过开关。这也是一种很好的方法。在学习了该语言的基础知识之后,我现在对学习更多复杂的部分感到非常舒服,发现这些小技巧也很有趣:)