如何重构切换语句

时间:2013-01-10 14:56:48

标签: c#

我正在尝试重构所有开关的母亲,我不确定如何做到这一点。这是现有的代码:

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

    }

如何将此切换重构为字典

3 个答案:

答案 0 :(得分:0)

实际上,编译器会将代码中的开关重构为字典,因为默认情况下字符串不能成为交换机的一部分。编译器将所有字符串放入字典中,并为每个字符串分配一个唯一的数字。

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

你切换现在看起来像这样:

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

重构

就我个人而言,我会保留你所做的陈述,因为重构不会让它变得更好,但你可以这样做:

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

现在你可以这样称呼它:

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

答案 1 :(得分:0)

编译器将大多数switch语句转换为Dictionary个对象。如果你想自己这样做,那很简单:

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

鉴于您正在访问Action中的局部变量,您需要在方法体内声明Dictionary。如果不是,您可以创建一个静态字典,以避免重新创建它。

然后for循环的主体变为:

dictionary[prepareElement.MappingName](prepareElement);

答案 2 :(得分:-1)

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