2010-07-15 30 views
9

Tengo los siguientes códigos y me gustaría escribirlos de forma que tenga una duplicación mínima de códigos.¿Cómo eliminar el código duplicado?

if (Categories != null) 
{ 
    bool flag=false; 
    foreach (dynamic usableCat in Category.LoadForProject(project.ID)) 
    { 
     foreach (dynamic catRow in Categories) 
     { 
      if (usableCat.ID == catRow.ID) 
       flag = true;        
     } 
     if (!flag) 
     { 
      int id = usableCat.ID; 
      Category resolution = Category.Load(id); 
      resolution.Delete(Services.UserServices.User); 
     } 
    } 
} 
if (Priorities != null) 
{ 
    bool flag = false; 
    foreach (dynamic usableCat in Priority.LoadForProject(project.ID)) 
    { 
     foreach (dynamic catRow in Priorities) 
     { 
      if (usableCat.ID == catRow.ID) 
       flag = true; 
     } 
     if (!flag) 
     { 
      int id = usableCat.ID; 
      Priority resolution = Priority.Load(id); 
      resolution.Delete(Services.UserServices.User); 
     } 
    } 
} 

Tenga en cuenta que la Categoría y la prioridad no tienen un tipo de base común o interfaz que incluya ID.

+3

Asumo que no tiene acceso para cambiar las clases de prioridad o categoría ? – RCIX

+3

En su ejemplo de código, está usando 'dynamic' donde parece que podría usar' var' (early-binding) en su lugar. Parece que lo que realmente quieres es usar 'dynamic' para obtener semántica de enlace tardío, en cuyo punto no importará que no haya un tipo de base común, de todos modos puedes usar el campo' ID'. (Es decir, parece que desea usar [pato escribiendo] (http://en.wikipedia.org/wiki/Duck_typing).) –

+0

+1 para pato escribir :) – onof

Respuesta

3

Permítanme sugerir un enfoque alternativo: En lugar de factorización de la cosa flag, utilizar LINQ para eliminar la necesidad para el lazo de la bandera:

if (Categories != null) 
{ 
    foreach (var usableCat in Category.LoadForProject(project.ID)) 
    { 
     if (!Categories.Any(row => usableCat.ID == row.ID)) 
      Category.Load(usableCat.ID).Delete(Services.UserServices.User); 
    } 
} 
if (Priorities != null) 
{ 
    foreach (var usablePri in Priority.LoadForProject(project.ID)) 
    { 
     if (!Priorities.Any(row => usablePri.ID == row.ID)) 
      Priority.Load(usablePri.ID).Delete(Services.UserServices.User); 
    } 
} 
+0

gracias, realmente útil, pero aún así mi problema para eliminar la duplicación de código aún no está resuelto. – learning

+0

@ user281180: ¿Por qué? La respuesta de onof se ve bastante bien para mí ... – Heinzi

7
void DeleteUsable<Ttype>(IEnumerable<Ttype> usables, IEnumerable<Ttype> collection, Func<int, Ttype> load) 
{ 
    bool flag = false; 
    foreach (dynamic usableCat in usables) 
       { 
        foreach (dynamic catRow in collection) 
        { 
         if (usableCat.ID == catRow.ID) 
          flag = true; 
        } 
        if (!flag) 
        { 
         int id = usableCat.ID; 
         Ttype resolution = load(id); 
         resolution.Delete(Services.UserServices.User); 
        } 
       } 
} 

Editar: llaman:

if (Categories != null) 
    DeleteUsable(Category.LoadForProject(project.ID), Categories, Categoriy.Load); 
if (Priorities != null) 
    DeleteUsables(Priority.LoadForProject(project.ID), Priorities, Priority.Load); 
+0

Gracias, pero ¿cómo llamar a la función con el ejemplo dado? – learning

+0

Agregué el código para llamar a la función. – onof

+0

No podrá llamar al método Eliminar. – Christian

2

me gustaría recomendar un método como este (ya que tiene acceso a los tipos dinámicos):

void DeleteUsables(dynamic usablesResource, dynamic usablesCatalog) 
{ 
    bool flag = false; 
    foreach (dynamic usableCat in usablesCatalog.LoadForProject(project.ID)) 
    { 
     foreach (dynamic catRow in usablesResource) 
     { 
      if (usableCat.ID == catRow.ID) 
       flag = true;        
     } 
     if (!flag) 
     { 
      int id = usableCat.ID; 
      dynamic resolution = usablesCatalog.Load(id); 
      resolution.Delete(Services.UserServices.User); 
     } 
    } 

} 

que luego se llamarían como este:

if (Categories != null) 
{ 
    DeleteUsables(Categories, Category) 
} 
if (Priorities != null) 
{ 
    DeleteUsables(Priorities, Priority) 
} 
+0

Gracias por responder, estoy teniendo el error: 'System.Array' no contiene una definición para 'LoadForProject' – learning

+0

Parece que RCIX pasó por alto que 'Categoría' y' Categorías' son dos cosas diferentes en su proyecto. Si 'Categoría' es un objeto (en lugar de una clase), puede pasarlo como un parámetro dinámico adicional. – Heinzi

+0

@Heinzi: gracias, lo arreglé. @user: allí tienes, no pude pensar en un buen nombre para el segundo parámetro. Quizás podrías? – RCIX

Cuestiones relacionadas