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