J'ai le nom du "tri par propriété" dans une chaîne. Je devrai utiliser Lambda / Linq pour trier la liste des objets.
Ex:
public class Employee
{
public string FirstName {set; get;}
public string LastName {set; get;}
public DateTime DOB {set; get;}
}
public void Sort(ref List<Employee> list, string sortBy, string sortDirection)
{
//Example data:
//sortBy = "FirstName"
//sortDirection = "ASC" or "DESC"
if (sortBy == "FirstName")
{
list = list.OrderBy(x => x.FirstName).toList();
}
}
- Au lieu d'utiliser un tas d'if pour vérifier le nom de champ (sortBy), existe-t-il une façon plus propre de faire le tri
- Le type est-il conscient du type de données?
c#
linq
lambda
linq-to-objects
DotnetDude
la source
la source
==
... quoi?Réponses:
Cela peut être fait comme
Le framework .NET transforme le lambda
(emp1,emp2)=>int
en unComparer<Employee>.
Cela a l'avantage d'être fortement typé.
la source
list.sort(functionDeclaredElsewhere)
Une chose que vous pourriez faire est de changer
Sort
afin de mieux utiliser les lambdas.Vous pouvez maintenant spécifier le champ à trier lors de l'appel de la
Sort
méthode.la source
Vous pouvez utiliser Reflection pour obtenir la valeur de la propriété.
Où TypeHelper a une méthode statique comme:
Vous pouvez également consulter Dynamic LINQ à partir de la bibliothèque d'échantillons VS2008 . Vous pouvez utiliser l'extension IEnumerable pour convertir la liste en un IQueryable, puis utiliser l'extension Dynamic Link OrderBy.
la source
collection.ToList().OrderBy(x => TypeHelper.GetPropertyValue( x, sortBy)).ToList();
Voici comment j'ai résolu mon problème:
la source
Construire l'ordre par expression peut être lu ici
Sans vergogne volé de la page en lien:
la source
Vous pouvez utiliser la réflexion pour accéder à la propriété.
Remarques
la source
Trier utilise l'interface IComparable, si le type l'implémente. Et vous pouvez éviter les ifs en implémentant un IComparer personnalisé:
puis
la source
Réponse pour 1:
Vous devriez pouvoir créer manuellement une arborescence d'expressions qui peut être passée dans OrderBy en utilisant le nom comme chaîne. Ou vous pouvez utiliser la réflexion comme suggéré dans une autre réponse, ce qui pourrait être moins de travail.
Modifier : Voici un exemple pratique de construction manuelle d'un arbre d'expression. (Tri sur X.Value, quand on ne connaît que le nom "Value" de la propriété). Vous pourriez (devriez) construire une méthode générique pour le faire.
Cependant, pour construire un arbre d'expression, vous devez connaître les types participants. Cela pourrait ou non être un problème dans votre scénario d'utilisation. Si vous ne savez pas sur quel type vous devez trier, il sera probablement plus facile d'utiliser la réflexion.
Réponse pour 2 .:
Oui, puisque Comparer <T> .Par défaut sera utilisé pour la comparaison, si vous ne définissez pas explicitement le comparateur.
la source
Un autre, cette fois pour tout IQueryable:
Vous pouvez passer plusieurs critères de tri, comme ceci:
la source
La solution fournie par Rashack ne fonctionne malheureusement pas pour les types de valeur (int, enums, etc.).
Pour qu'il fonctionne avec n'importe quel type de propriété, voici la solution que j'ai trouvée:
la source
Ajoutant à ce que @Samuel et @bluish ont fait. C'est beaucoup plus court car l'Enum n'était pas nécessaire dans ce cas. De plus, comme bonus supplémentaire lorsque l'Ascendant est le résultat souhaité, vous ne pouvez passer que 2 paramètres au lieu de 3 car true est la réponse par défaut au troisième paramètre.
la source
Si vous obtenez le nom et la direction de tri de la colonne sous forme de chaîne et que vous ne souhaitez pas utiliser la syntaxe switch ou if \ else pour déterminer la colonne, cet exemple peut vous intéresser:
Solution basée sur l'utilisation de Dictionary qui connecte les colonnes de tri nécessaires via Expression> et sa chaîne de clé.
la source