Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用动作字典而不是switch语句_C#_Refactoring_Polymorphism_Conditional Statements - Fatal编程技术网

C# 使用动作字典而不是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

我只是在回顾我的一些旧代码(有一些空闲时间),我注意到一个相当长的switch语句。由于获得了新的知识,我将其重构为以下形式:

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}
};
}
返回命令;
}
}
}
编辑

从概念上看,用dictionary
TryGetValue
替换long
swicth/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虚拟函数和一个字典,其中包含替换开关的抽象类。现在,调用方可以缓存从字典中获取的继承类并调用其虚拟函数,而不是每次调用都通过开关。这也是一种很好的方法。在学习了该语言的基础知识之后,我现在对学习更多复杂的部分感到非常舒服,发现这些小技巧也很有趣:)