0

Je voudrais prendre la classe ResultSet montrée ci-dessous et la modifier pour qu'elle soit générique. Comme vous pouvez le voir, il accepte seulement la liste de produits mais je voudrais qu'il prenne List-OneOfMyModels> ou List-T> pour le plaisir de réutiliser le code dans mes contrôleurs.Comment puis-je prendre une classe et autoriser les méthodes à accepter une liste générique

public class ResultSet 
{ 
    public List<Product> GetResult(string search, string sortOrder, int start, int length, List<Product> dtResult, List<string> columnFilters) 
    { 
     return FilterResult(search, dtResult, columnFilters).SortBy(sortOrder).Skip(start).Take(length).ToList(); 
    } 

    public int Count(string search, List<Product> dtResult, List<string> columnFilters) 
    { 
     return FilterResult(search, dtResult, columnFilters).Count(); 
    } 

    private IQueryable<Product> FilterResult(string search, List<Product> dtResult, List<string> columnFilters) 
    { 
     IQueryable<Product> results = dtResult.AsQueryable(); 

     results = results.Where(p => (search == null || (p.Name != null && p.Name.ToLower().Contains(search.ToLower()) || p.PublicDisplayNo != null && p.PublicDisplayNo.ToLower().Contains(search.ToLower()))) 
      ); 

     return results; 
    } 
} 

Et dans mon contrôleur j'appelle la méthode comme ceci:

public JsonResult DataHandler(DTParameters param) 
    { 
     try 
     { 
      var dtsource = _context.Products.ToList(); 

      List<String> columnSearch = new List<string>(); 

      foreach (var col in param.Columns) 
      { 
       columnSearch.Add(col.Search.Value); 
      } 

      List<Product> data = new ResultSet().GetResult(param.Search.Value, param.SortOrder, param.Start, param.Length, dtsource, columnSearch); 
      int count = new ResultSet().Count(param.Search.Value, dtsource, columnSearch); 
      DTResult<Product> result = new DTResult<Product> 
      { 
       draw = param.Draw, 
       data = data, 
       recordsFiltered = count, 
       recordsTotal = count 
      }; 
      return Json(result); 
     } 
     catch (Exception ex) 
     { 
      return Json(new { error = ex.Message }); 
     } 
    } 
+0

public liste getResult (paramètres ...., liste dtResult, param). Vous devez rendre la méthode générique pour passer la liste générique en tant que paramètre. Vous pouvez également renvoyer la liste . –

Répondre

0

Cela devrait vous y aller:

using System.Collections.Generic; 
using System.Linq; 
using System.Runtime.InteropServices.ComTypes; 

public class ResultSet 
{ 
    public List<T> GetResult<T>(string search, string sortOrder, int start, int length, List<T> dtResult, List<string> columnFilters) where T : class 
    { 
     return FilterResult(search, dtResult, columnFilters).OrderBy(sortOrder).Skip(start).Take(length).ToList(); 
    } 
    public int Count<T>(string search, List<T> dtResult, List<string> columnFilters) where T : class 
    { 
      return FilterResult(search, dtResult, columnFilters).Count(); 
    } 

    private IQueryable<T> FilterResult<T>(string search, List<T> dtResult, List<string> columnFilters) where T : class 
    { 
     IQueryable<T> results = dtResult.AsQueryable(); 

     results = results.Where(p => (search == null || (p.Name != null && p.Name.ToLower().Contains(search.ToLower()) || p.PublicDisplayNo != null && p.PublicDisplayNo.ToLower().Contains(search.ToLower())))); 

     return results; 
    } 
} 

Cela ne soutiendra pas les cas où vous utilisez des propriétés sur le type générique, T, parce que je l'ai seulement tapé comme une classe. Vous pouvez changer la frappe en suivant la documentation here. Vous devrez le taper avec une classe de base ou une interface pour que les choses comme p.Name fonctionnent.

+0

La méthode FilterResult ne sera même pas acceptée par le compilateur lors de la compilation. Le compilateur ne sera pas en mesure de résoudre les valeurs de propriété des types génériques. – devTimmy

+0

@devTimmy, oui. C'est pour vous aider à démarrer, je voudrais en savoir plus sur vos modèles pour fournir une réponse complète. Relisez la note en bas. Si vous avez une classe de base ou une interface, alors vous tapez T à cela. La classe de base ou l'interface doit avoir les membres que vous souhaitez réutiliser dans FilterResult. Jetez un coup d'œil sur le lien de la documentation que j'ai partagé. Cela devrait faire le reste du chemin. – rkralston

0

Vous auriez à faire le générique entier comme public class ResultSet<T> ou faire les méthodes dans la classe ont des types génériques d'entrée et de retour comme si public List<T> GetResult(params).

Mais ceci introduit un nouveau problème dans la méthode de résultat du filtre qui utilise la classe Products pour effectuer une recherche et un filtrage selon ses propriétés. Utilisez Reflections in c#, System.Reflection pour rechercher des valeurs de propriété de classe de types génériques.