Рефакторинг моего кода C # - оператор Switch - PullRequest
4 голосов
/ 18 февраля 2009

У меня есть следующий код, который я сейчас использую .... По сути, этот метод назначает правильный логический флаг (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 = логический

User.TASKX = логический

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

Ответы [ 6 ]

9 голосов
/ 18 февраля 2009

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

Dictionary<ClassStructure.Tasks_CallIDs_Strings, Task_Flag>

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

Edit:

Как теперь все могут видеть, реальная проблема рефакторинга этого примера заключается в рефакторинге User.TASKX. Достаточно сделать список, так как он может быть проиндексирован той же строкой

2 голосов
/ 18 февраля 2009

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

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, в User ...

2 голосов
/ 18 февраля 2009

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

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);
1 голос
/ 29 ноября 2011

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

1 голос
/ 18 февраля 2009

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

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

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

Ваш метод становится:

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

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

1 голос
/ 18 февраля 2009

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

например.

User.Tasks[Task_CallID] = data.Task_Flag;

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

  1. Поддерживать отображение из Task_Call_ID в ссылку PropertyInfo и использовать это для установки правильного свойства
  2. Используйте отражение, чтобы найти свойство на основе бит числа (X) и установить это свойство

Оба они основаны на отражении и немного противны.

...