0

我正在尝试重构所有开关之母,但我不确定该怎么做。这是现有的代码:

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

    }

我将如何重构这个 Switch to a Dictionary

4

3 回答 3

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); 
}
于 2013-01-10T15:07:39.693 回答
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);
于 2013-01-10T15:11:33.250 回答
-1

关于什么

Dictionary<string, string> fileMappings =
   prepareElements.ToDictionary(e => e.MappingName, e => e.FileName);
于 2013-01-10T15:00:49.167 回答