2 votes

Est-il possible d'extraire une liste de valeurs de champ particulières à partir d'une collection d'objets génériques en C#?

J'ai la méthode suivante dans une classe que j'utilise pour la pagination dans mon application:

public static PagedList ToPagedList(IEnumerable source, int pageNumber, int pageSize)
        {
            var count = source.Count();
            var items = source
              .Skip((pageNumber - 1) * pageSize)
              .Take(pageSize).ToList();

            return new PagedList(items, count, pageNumber, pageSize);
        }

Dans cette méthode, je passe une collection d'objets génériques en tant que IEnumerable source qui, quel que soit le type, aura toujours un champ Id. Ce que je voudrais faire, c'est extraire tous les Id de ces objets et les stocker dans une liste à passer au constructeur de ma PagedList. Est-ce possible?

4voto

Serge Points 7425

La meilleure façon serait de créer une interface

public interface IBaseClass{
  public int Id {get; set;}
}

dans ce cas, vous pourriez changer l'en-tête de la méthode

static PagedList ToPagedList(IEnumerable source, int pageNumber, int pageSize) 
                    where T : IBaseClass

et les identifiants

var ids=items.Select(i => i.Id ).ToList();

2voto

Tuan Tran Points 198

Oui, c'est possible. Vous pouvez utiliser Réflexion pour obtenir la valeur d'une propriété.

item.GetType().GetProperty("Id").GetValue(item, null);

Modifier : Répondre au commentaire de @CoolBots

Si Id est un champ, vous pouvez utiliser GetField à la place de GetProperty

item.GetType().GetField("Id").GetValue(item, null);

mais si l'élément n'a pas la propriété "Id", ce code échouera, alors n'oubliez pas de vérifier pour le null.

1voto

rfmodulator Points 1548

Une interface serait le meilleur moyen, mais vous avez spécifiquement dit "champ" et les interfaces ne peuvent pas contenir de champs.

Vous pourriez contourner cette limitation avec une classe de base abstraite, mais vous ne pouvez pas avoir plusieurs classes de base sur une seule classe (si applicable).

... Tout cela suppose que vous avez la capacité de modifier ces classes.

Une autre façon de faire cela serait :

public static PagedList<T> ToPagedList<T>(IEnumerable<T> source, int pageNumber, int pageSize)
{
    var count = source.Count();

    var items = source
        .Skip((pageNumber - 1) * pageSize)
        .Take(pageSize).ToList();

    var ids = items
        .Select(i => ((dynamic)i).Id)   // le champ est ** toujours ** nommé "Id"
        .Cast<int>()                    // son type est ** toujours ** int
        .ToList();

    return new PagedList<T>(items, count, pageNumber, pageSize/*, ids*/); // passer les ids
}

Cela suppose que le champ en question est nommé "Id", et c'est un int.

Adaptez en conséquence et gérez les erreurs potentielles.

Je pense que j'ai initialement mal compris la question, le commentaire de @Dusan m'a amené à réévaluer et mettre à jour le code.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X