es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Haciendo un método genérico.

Tengo el siguiente objeto:

public class Store : BaseEntity
{
  public virtual List<consumerclubdto>? RelatedConsumerClubs { get; set; }
  public virtual List<giftdto>? RelatedGifts { get; set; }
}

Estas dos listas implementan la misma interfaz.

Tengo el siguiente método de extensión que se ejecuta en cada lista. En este momento, tengo duplicado este método: uno se ejecuta en ConsumerClubDto y el otro en GiftDto.

public static async Task UpdateList(this List<consumerclubdto>? clubsDto, Store storeFromRepo, AppDbContext dbContext)
{
  if (clubsDto?.Count > 0)
  {
    foreach (ConsumerClubDto clubDto in clubsDto)
    {
      if ((storeFromRepo.RelatedConsumerClubs?.FindIndex(x => x.Id == clubDto.Id) == -1))
      {
        ConsumerClub t = await dbContext.ConsumerClubs.FindAsync(clubDto.Id);
        storeFromRepo.RelatedConsumerClubs.Add(t);
      }
    }
    List<consumerclub> clubsToRemove = new List<consumerclub>();
    foreach (ConsumerClub club in storeFromRepo.RelatedConsumerClubs)
    {
      if (clubsDto.FindIndex(x => x.Id == club.Id) == -1)
        clubsToRemove.Add(club);
    }
    if (clubsToRemove.Count > 0)
    {
      foreach (ConsumerClub club in clubsToRemove)
        storeFromRepo.RelatedConsumerClubs.Remove(club);
    }
  }
}

Estoy seguro de que puedo escribir un método genérico y evitar duplicar el código. No estoy seguro de cómo hacerlo.

Se aceptan sugerencias.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Para evitar duplicar el código y crear un método genérico, puedes seguir estos pasos:

    1. Convertir el método de extensión desde una lista de ConsumerClubDto a una lista de T, donde T es el tipo que implementa la interfaz.
    2. Modificar el método para utilizar el tipo T en lugar de ConsumerClubDto.
    3. Utilizar la interfaz en lugar del nombre de la clase siempre que sea posible.
    4. Actualizar la firma del método en consecuencia, utilizando el nombre de la interfaz en lugar del nombre de la clase concreta.
    5. Actualizar el código que llama al nuevo método genérico en lugar de los métodos duplicados.

    Aquí tienes un ejemplo de cómo podría verse el método genérico:

    public static async Task UpdateList<t>(this List<t>? listaActualizar, Store almacenDesdeRepo, AppDbContext dbContext) where T : IRelatedDto
    {
        if (listaActualizar?.Count > 0)
        {
            foreach (var item in listaActualizar)
            {
                if ((item.Id > 0 && almacenDesdeRepo.RelatedConsumerClubs?.FindIndex(x => x.Id == item.Id) == -1))
                {
                    var t = await dbContext.Set<t>().FindAsync(item.Id);
                    if (t != null)
                    {
                        almacenDesdeRepo.RelatedConsumerClubs.Add(t as ConsumerClub);
                    }
                }
            }
            var itemsToRemove = new List<object>();
            foreach (var item in almacenDesdeRepo.RelatedConsumerClubs)
            {
                if (listaActualizar.FindIndex(x => x.Id == item.Id) == -1)
                    itemsToRemove.Add(item);
            }
            if (itemsToRemove.Count > 0)
            {
                foreach (var item in itemsToRemove)
                    almacenDesdeRepo.RelatedConsumerClubs.Remove(item as ConsumerClub);
            }
        }
    }
    

    Ten en cuenta que utiliza la interfaz IRelatedDto en lugar de ConsumerClubDto o GiftDto, y el método Set de dbContext para consultar la base de datos para el tipo T. También ten en cuenta el uso del operador as para convertir el elemento a ConsumerClub antes de agregarlo a la lista.

    Finalmente, para llamar al nuevo método genérico, harías algo como esto:

    storeFromRepo.RelatedConsumerClubs.UpdateList(clubsDto, dbContext);
    storeFromRepo.RelatedGifts.UpdateList(giftsDto, dbContext);
    

    donde clubsDto y giftsDto son la lista de objetos que se van a actualizar, y dbContext es el contexto de la base de datos.

Comments are closed.