简体   繁体   English

如何重构Switch语句

[英]How can I refactor the Switch Statements

I am trying to refactor the mother of all switches and am not really sure how to do it. 我试图重构所有开关之母,但我不确定如何做到这一点。 Here is the existing code: 这是现有的代码:

    private void SetPrepareFiles(
                  ObservableCollection<PrepareElement> prepareElements)
    {
        DateTime fileLoadDate = DateTime.Now;


        string availabilityRequestFile = string.Empty;
        string infrastructureFile = string.Empty;
        string gsQualityFile = string.Empty;
        string pvdnpProducedFile = string.Empty;
        string docFile = string.Empty;
        string actualCurrentStateFile = string.Empty;
        string actualIpPlanFile = string.Empty;


        foreach (var prepareElement in prepareElements)
        {
            switch (prepareElement.MappingName)
            {
                case "AvailabilityRequest":
                    availabilityRequestFile = prepareElement.FileName;
                    break;
                case "SystemInformation":
                    docFile = prepareElement.FileName;
                    break;
                case "ITStatus":
                    infrastructureFile = prepareElement.FileName;
                    break;
                case "ActualIPPlan":
                    actualIpPlanFile = prepareElement.FileName;
                    break;
                case "ActualCurrentState":
                    actualCurrentStateFile = prepareElement.FileName;
                    break;
                case "Produced":
                    pvdnpProducedFile = prepareElement.FileName;
                    break;
                case "Quality":
                    QualityFile = prepareElement.FileName;
                    break;
            }

        }   


        var fc = new FilesConverter.FilesConverter();           
        fc.SetCommonFiles(availabilityRequestFile, actualCurrentStateFile,
                               actualIpPlanFile, fileLoadDate);         

    }

How would I refactor this Switch to a Dictionary 我将如何重构“切换到字典”

Actually the compiler refactors the switch in your code into a dictionary, because strings cannot be a part of a switch by default. 实际上,编译器将代码中的开关重构为字典,因为默认情况下字符串不能成为开关的一部分。 The compiler puts all of your strings into a dictionary and gives each of them a unique number. 编译器将所有字符串放入字典中,并为每个字符串赋予唯一编号。

Dictionary<String, Int32> _CompilerGeneratedList = .... {
    { "AvailabilityRequest" , 1 }
};

You switch looks now like this: 您现在切换如下所示:

Int32 value;
if (_CompilerGeneratedList.TryGetValue(myString, out value))
{
    switch (value) { ... }
}

Refactoring 重构

Personally i would keep the the statement you did because refactoring doesn't makes it so much better but you could do it this way: 我个人会保留您所做的声明,因为重构并不能使它变得更好,但是您可以这样进行:

// Nested Private class
class DataHolder
{
    public String AvailabilityRequestFile { get; set; }
    public String PvdnpProducedFile { get; set; }
}

static Dictionary<String, Action<String, DataHolder>> DataUpdateActions = new Dictionary<String, Action<String, DataHolder>>
{
    { "AvailabilityRequest", (s,d) => d.AvailabilityRequestFile = s; }
    { "Produced", (s,d) => d.PvdnpProducedFile = s; }
};

Now you can call it this way: 现在您可以这样称呼:

DataHolder holder = new DataHolder();
foreach (var prepareElement in prepareElements)
{
    // Do this with try get value to prevent errors
    DataUpdateActions[prepareElement.MappingName](s, holder);

    var fc = new FilesConverter.FilesConverter();           
    fc.SetCommonFiles(holder.AvailabilityRequestFile, holder.ActualCurrentStateFile,
                           holder.ActualIpPlanFile, holder.FileLoadDate); 
}

Most switch statements are converted into Dictionary objects by the compiler. 编译器将大多数switch语句转换为Dictionary对象。 If you would like to do so yourself it's simple enough: 如果您想自己做,那就足够简单了:

var dictionary = new Dictionary<string, Action>()
{
    {"AvailabilityRequest", prepareElement => availabilityRequestFile = prepareElement.FileName},
    {"SystemInformation", prepareElement => docFile = prepareElement.FileName}
    //TODO add the others
};

Given that you're accessing local variables in the Action , you'll need to declare the Dictionary inside of the method body. 假设您要在Action访问局部变量,则需要在方法主体内部声明Dictionary If you weren't, you could create a static dictionary to avoid re-creating it. 如果不是这样,则可以创建一个静态字典以避免重新创建它。

Then the body of your for loop becomes: 然后,您的for循环的主体变为:

dictionary[prepareElement.MappingName](prepareElement);

What about 关于什么

Dictionary<string, string> fileMappings =
   prepareElements.ToDictionary(e => e.MappingName, e => e.FileName);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM