Refactor мой код С# - оператор switch

У меня есть следующий код, который я использую в настоящее время... В основном, этот метод назначает правильный логический флаг (TRUE/FALSE) для каждой задачи. Поскольку все больше и больше задач необходимо добавить. Я вижу, что оператор switch должен расти, чтобы удовлетворить каждую задачу.

Должен быть более простой способ: сохранить метод небольшим.

Код: (соглашение об именовании забывания, оно было изменено для публикации)

public ClassStructure.User AssignTaskStatusToUser(ClassStructure.User,
                                                  List<ClassStructure.Tasks> TaskStatus)
{
    foreach (ClassStructure.Tasks data in TaskStatus)
    {
        string Task_CallID = data.Task_Call_ID;

        switch (Task_CallID)
        {
            case ClassStructure.Tasks_CallIDs_Strings.TASK1:
                User.TASK1 = data.Task_Flag;
                break;

            case ClassStructure.Tasks_CallIDs_Strings.TASK2:
                User.TASK2 = data.Task_Flag;
                break;

            case ClassStructure.Tasks_CallIDs_Strings.TASK3:
                User.TASK3 = data.Task_Flag;
                break;
        }
    }

    return User;
}

ClassStructure.Tasks_CallIDs_Strings = String Представление задач

data.Task_Flag = boolean

User.TASKX = boolean

Любая обратная связь приветствуется. Я уверен, что есть простое решение.

Ответ 1

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

Dictionary<ClassStructure.Tasks_CallIDs_Strings, Task_Flag>

и получить значения путем сопоставления строк CallID.

Edit:

Как теперь все видят, реальной проблемой рефакторинга этого примера является рефакторинг User.TASKX. Сделать его список должен быть достаточно - так как он может быть проиндексирован одной строкой ClassStructure.Tasks_CallIDs_Strings

Ответ 2

О... Пересмотрите схему именования.

public delegate void TaskAssigner(User user, bool taskFlag)

IDictionary<string, TaskAssigner> taskAssigners = new Dictionary<string, TaskAssigner>();

...

taskAssigners.Add(ClassStructure.Tasks_CallIDs_Strings.TASK1, (u, t) => u.TASK1 = t;);
taskAssigners.Add(ClassStructure.Tasks_CallIDs_Strings.TASK2, (u, t) => u.TASK2 = t;);

...

foreach(ClassStructure.Tasks data in TaskStatus)
    taskAssigners[data.Task_Call_ID](user, data.Task_Flag);

Ответ 3

Я думал что-то вроде этого - но, возможно, я пропустил то, для чего все это?

public class User
{
    private Dictionary<string,Task> tasks;

    internal Dictionary<string,Task> Tasks
    {
      get { return tasks; }
      set { tasks = value; }
    }

    internal void AddTask(Task task)
    {
        tasks.Add(task.Task_Call_ID,task);
    }

    internal void AddTasks(List<Task> task)
    {
        foreach(Task task in Tasks)
        {
            tasks.Add(task.Task_Call_ID,task);
        }
    }
}

Класс Task может иметь свойства, позволяющие вам передать указатель на функцию (к функции, которая фактически выполняет задачу), если вам нужна такая гибкость, - и вы могли бы добавить и другие методы, такие как ExecuteTasks для пользователя...

Ответ 4

Вместо этого вы можете иметь массив/список задач и использовать Task_CallID в качестве индекса для этого?

например.

User.Tasks[Task_CallID] = data.Task_Flag;

Если у вас есть все участники, есть другие варианты:

  • Сохраняйте сопоставление от Task_Call_ID к ссылке PropertyInfo и используйте это, чтобы установить правильное свойство
  • Используйте отражение, чтобы найти свойство, основанное на бите числа (X), и установите это свойство

Оба они основаны на размышлении и немного неприятны.

Ответ 5

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

Класс пользователя

public List<ClassStructure.Tasks> Tasks {
    get; set;
}

Ваш метод будет:

public void AssignTasks(User user, List<ClassStructure.Tasks> TaskStatus)    
{
    user.Tasks.AddRange(TaskStatus)   
}

Это означает, что вам вообще не нужен этот метод. Затем ваш аксессуар запускается. Найдите в пользователе задачи и проверите флаг "Задачи".

Ответ 6

Словарь - отличная альтернатива этому. Однако, когда коммутатор/регистр становится очень сложным, посмотрите на использование шаблона стратегии (не для вашего сценария).