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

    }

このスイッチをディクショナリにリファクタリングするにはどうすればよいですか

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 に答える