Более эффективный / менее любительский способ сделать что-то на основе выбранного параметра вместо массивного if-дерева?

#c# #list #loops #if-statement #resources

#c# #Список #циклы #if-statement #Ресурсы

Вопрос:

Это беспокоило меня некоторое время, но я не уверен, есть ли какие-либо способы улучшить это… В основном в этом проекте у меня есть список, составленный из карточек, которые я хочу добавить к окончательному текстовому выводу. Я перебираю список, и на каждой итерации я просматриваю множество операторов if, проверяя имя карты, и если имя карты узнаваемо, я добавляю блок кода в строку, специфичную для этой карты. Вот некоторые вещи, которые могут помочь / ограничить решения:

  • Блоки кода, которые добавляются в строку, которую я компилирую, хранятся в файле ресурсов моего проекта. Вы увидите в приведенном ниже коде, что они называются m1735xxxx. Может быть, есть способ выполнить поиск по этим строкам в моем файле ресурсов, очень похожий на список?

  • все возможные элементы в считываемом списке известны и имеют блок кода, который идет с ними, хранящийся в моих ресурсах.

Код:

 int numCards = moduleList.Count;
while (moduleList.Any())
{
    SplashScreen.SetProgress((int)((numCards - moduleList.Count) * 100.00 / numCards));
    if (moduleList[0].name.Contains("1756"))
    {
        etrCount  ;
        string newCard = Cards.m1756EN2T.Replace("@SLOT@", etrCount.ToString());
        newCard = newCard.Replace("@ETHERNUM@", etrCount.ToString());
        finalOutput = finalOutput   newCard;
        finalOutput  = Environment.NewLine;
        finalOutput  = Environment.NewLine;
        moduleList.RemoveAt(0);
        modSlotCount = 0;
    }
    else if (moduleList[0].name.Contains("AENTR"))
    {
        aentrCount  ;
        modSlotCount = 0;
        string newCard = Cards.m1734AENTR.Replace("@SLOT@", modSlotCount.ToString());
        newCard = newCard.Replace("@SIZE@", numMods[aentrCount].ToString());
        newCard = newCard.Replace("@AENTRNUM@", aentrCount.ToString());
        newCard = newCard.Replace("@ETHERNUM@", etrCount.ToString());
        finalOutput = finalOutput   newCard;
        finalOutput  = Environment.NewLine;
        finalOutput  = Environment.NewLine;
        moduleList.RemoveAt(0);
        modSlotCount  ;
    }
    while (moduleList.Any() amp;amp; !moduleList[0].name.Contains("AENTR") amp;amp; !moduleList[0].name.Contains("1756"))
    {
        if (moduleList[0].name == "1734-IB8S")
        {
            string newCard = Cards.m1734IB8S.Replace("@SLOT@", modSlotCount.ToString());
            newCard = newCard.Replace("@AENTRNUM@", aentrCount.ToString());
            finalOutput = finalOutput   newCard;
            finalOutput  = Environment.NewLine;
            finalOutput  = Environment.NewLine;
            moduleList.RemoveAt(0);
            modSlotCount  ;
        }
        else if (moduleList[0].name == "1734-OB8S")
        {
            string newCard = Cards.m1734OB8S.Replace("@SLOT@", modSlotCount.ToString());
            newCard = newCard.Replace("@AENTRNUM@", aentrCount.ToString());
            finalOutput = finalOutput   newCard;
            finalOutput  = Environment.NewLine;
            finalOutput  = Environment.NewLine;
            moduleList.RemoveAt(0);
            modSlotCount  ;
        }
        else if (moduleList[0].name == "1734-IB4D")
        {
            string newCard = Cards.m1734IB4D.Replace("@SLOT@", modSlotCount.ToString());
            newCard = newCard.Replace("@AENTRNUM@", aentrCount.ToString());
            finalOutput = finalOutput   newCard;
            finalOutput  = Environment.NewLine;
            finalOutput  = Environment.NewLine;
            moduleList.RemoveAt(0);
            modSlotCount  ;
        }
        else if (moduleList[0].name == "1734-OB4E")
        {
            string newCard = Cards.m1734OB4E.Replace("@SLOT@", modSlotCount.ToString());
            newCard = newCard.Replace("@AENTRNUM@", aentrCount.ToString());
            finalOutput = finalOutput   newCard;
            finalOutput  = Environment.NewLine;
            finalOutput  = Environment.NewLine;
            moduleList.RemoveAt(0);
            modSlotCount  ;
        }
        else if (moduleList[0].name == "1734-IE2C")
        {
            string newCard = Cards.m1734IE2C.Replace("@SLOT@", modSlotCount.ToString());
            newCard = newCard.Replace("@AENTRNUM@", aentrCount.ToString());
            finalOutput = finalOutput   newCard;
            finalOutput  = Environment.NewLine;
            finalOutput  = Environment.NewLine;
            moduleList.RemoveAt(0);
            modSlotCount  ;
        }
        else if (moduleList[0].name == "1734-OE2C")
        {
            string newCard = Cards.m1734OE2C.Replace("@SLOT@", modSlotCount.ToString());
            newCard = newCard.Replace("@AENTRNUM@", aentrCount.ToString());
            finalOutput = finalOutput   newCard;
            finalOutput  = Environment.NewLine;
            finalOutput  = Environment.NewLine;
            moduleList.RemoveAt(0);
            modSlotCount  ;
        }
        else if (moduleList[0].name == "1734-IR2")
        {
            string newCard = Cards.m1734IR2.Replace("@SLOT@", modSlotCount.ToString());
            newCard = newCard.Replace("@AENTRNUM@", aentrCount.ToString());
            finalOutput = finalOutput   newCard;
            finalOutput  = Environment.NewLine;
            finalOutput  = Environment.NewLine;
            moduleList.RemoveAt(0);
            modSlotCount  ;
        }
    }
}
  

Видите, что я подразумеваю под любительским стилем? Это работает, на это просто очень некрасиво смотреть.

Ответ №1:

Вы могли бы создать словарь, который сопоставляет ваши строки с именами полей ресурсов и выполняет поиск карты через диспетчер ресурсов:

 var mappings = new Dictionarx<string, string> { { "1734-IB8S", "m1734IB8S" }, { "1734-OB8S", "m1734OB8S" } /* ... */ }
var resourceManager = new ResourceManager("yourresourcefilename", typeof(Cards).Assembly);

while (moduleList.Any() amp;amp; !moduleList[0].name.Contains("AENTR") amp;amp; !moduleList[0].name.Contains("1756"))
{
    string resourceName;
    if (!mappings.TryGetValue(moduleList[0].name, out resourceName))
    {
        continue;
    }

    var field = resourceManager.GetString(resourceName);
    string newCard = field.Replace("@SLOT@", modSlotCount.ToString());
    newCard = newCard.Replace("@AENTRNUM@", aentrCount.ToString());
    finalOutput = finalOutput   newCard;
    finalOutput  = Environment.NewLine;
    finalOutput  = Environment.NewLine;
    moduleList.RemoveAt(0);
    modSlotCount  ;
}
  

Ответ №2:

Я предполагаю, что функциональность замены не всегда такая же простая «замена».

Вы могли бы создать словарь имен модулей, и каждый ключ в этом словаре ссылается на функцию, которая выполняет фактическую замену для этого ключа, например:

 Dictionary<string, Func<string, string>> functions = ...;
  

Тогда вы можете избежать всех этих if-операторов; и просто найти правильный ключ в словаре на основе moduleList[0].name и выполнить соответствующую функцию replace .

Комментарии:

1. Мне нравится эта идея, но тогда у меня не будет уродливого большого словарного объявления функций для каждой карты? Таких карт может быть 30-40, и это будет просто заменой одного уродливого блока кода другим.

2. Действительно, но все определения будут в одном месте, и у вас нет дублирующегося кода. Также прост в обслуживании. Если вам нужно добавить его, вы просто добавляете новый элемент в словарь.

3. итак, я так понимаю, что нет способа сделать что-то вроде: «foreach (строковый элемент в ресурсах) { // выполняйте мои сравнения }»