Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I avoid code duplication

Tags:

c#

I have the follwoing code and I would like to write it in a way that I have minimum lines of code and the work is done the same way. How can I do that?

List<Category> categoryList = new List<Category>();
categoryList = Category.LoadForProject(project.ID).ToList();
List<string> categories = new List<string>(Categories);
IList<Category> currentCategories = Category.LoadForProject(project.ID).ToList();
if (currentCategories != null)
{
    foreach (var existingCategories in currentCategories)
    {
        if (categories.Contains(existingCategories.Name))
           categories.Remove(existingCategories.Name);
        else
            existingCategories.Delete(Services.UserServices.User);
    }
    foreach (string item in categories)
    {
        Category category = new Category(project, item.ToString());
        category.Project = project;
        category.Save();
   }
}

List<string> priorities = new List<string>(Priorities);
IList<Priority> currentPriorities = Priority.LoadForProject(project.ID).ToList();
if (currentPriorities != null)
{
   foreach (var existingPriorities in currentPriorities)
   {
       if (priorities.Contains(existingPriorities.Name))
           priorities.Remove(existingPriorities.Name);
       else
           existingPriorities.Delete(Services.UserServices.User);
   }
   foreach (string item in priorities)
   {
       Priority priority = new Priority(project, item.ToString());
       priority.Project = project;
       priority.Save();
   }
}
like image 678
learning Avatar asked Jul 08 '10 12:07

learning


1 Answers

Something like this should do it:

public IList<T> DoYourThing<T>(IList<T> items, IList<T> currentItems, Project project) where T : CommonBaseType
{
  if (currentItems != null)
  {
    foreach (var existingItem in currentItems)
    {
      if (items.Contains(existingItem.Name))
        items.Remove(existingItem.Name);
      else
        existingItems.Delete(Services.UserServices.User);
    }
    foreach (string item in items)
    {
      T newItem = Activator.CreateInstance(typeof(T), new object[] {project, item.ToString()}) as T;
      newItem.Project = project;
      newItem.Save();
    }
  }

  return currentItems;
}

Then you can call it like this:

var currentCategories = DoYourThing(Categories.ToList(), Category.LoadForProject(project.ID).ToList());
var currentProjects = DoYourThing(Priorities.ToList(), Priority.LoadForProject(project.ID).ToList());

Finally, you should note two things in particular: First, there is a generic condition on the function where T : CommonBaseType. I am assuming that Category and Project have a common base type or interface that includes Name. If not, you should get rid of the condition and use Dynamic to get at Name.

Second, I am using Activator.Create to create the class for you. This is the tricky part that makes it difficult to figure out, if you don't know that trick

Good luck!

like image 126
Brian Genisio Avatar answered Sep 19 '22 14:09

Brian Genisio