使用Action词典而不是switch语句

Dar*_*ung 23 c# polymorphism refactoring conditional-statements

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

private Dictionary<string, Action> createView
    {
        get
        {
            return new Dictionary<string, Action>()
            {
                {"Standard", CreateStudySummaryView},
                {"By Group", CreateStudySummaryByGroupView},
                {"By Group/Time", CreateViewGroupByHour}
            };
        }
    }
Run Code Online (Sandbox Code Playgroud)

你会考虑这个好习惯,还是仅仅是一个超级丰富和不必要的案例?我渴望确保我学到的新技术,仅仅为了它而不是聪明,并且它们实际上为代码增加了好处.

谢谢.

And*_*erd 18

长切换语句是经典的难闻气味,并且始终是重构的目标.

这里执行的"标准"步骤是使用多态替换条件.这是Martin Fowler的书Refactoring(11年前出版于1999年)中列出的步骤之一.

现在,处理像对象这样的函数非常容易(例如使用Action),这可能是一个很好的解决方案.

不,我不认为你是聪明的.如果我想在将来添加其他选项,我可以很容易地看到需要做什么.


Tig*_*ran 9

根据您的应用程序,您可以避免始终构造新的字典对象,但将其声明为类成员,在第一次访问时初始化并始终返回相同的实例.但很难说,它是否真的符合您的需求.我的意思是这样的

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;
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

编辑

概念的角度来看,我用swicth/case字典替换长TryGetValue是一个很好的解决方案.

希望这可以帮助...


Eni*_*ity 5

这种方法非常好.

我不仅仅使用它Action.它对滤波器和选择器也非常有效.就像是:

var filters = new Dictionary<string, Func<MyEntity, bool>>()
{
    // ...
};

var query = entities.Where(filters["X"]);
Run Code Online (Sandbox Code Playgroud)