J'ai le nom de la propriété "trier par" dans une chaîne. J'aurai besoin d'utiliser Lambda/Linq pour trier la liste d'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();
}
}
Une chose que vous pourriez faire est de modifier Sort
pour qu'il fasse un meilleur usage des lambdas.
public enum SortDirection { Ascending, Descending }
public void Sort<TKey>(ref List<Employee> list,
Func<Employee, TKey> sorter, SortDirection direction)
{
if (direction == SortDirection.Ascending)
list = list.OrderBy(sorter);
else
list = list.OrderByDescending(sorter);
}
Maintenant vous pouvez spécifier le champ à trier en appelant la méthode Sort
.
Sort(ref employees, e => e.DOB, SortDirection.Descending);
Vous pouvez utiliser Reflection pour obtenir la valeur de la propriété.
list = list.OrderBy( x => TypeHelper.GetPropertyValue( x, sortBy ) )
.ToList();
Où TypeHelper a une méthode statique comme :
public static class TypeHelper
{
public static object GetPropertyValue( object obj, string name )
{
return obj == null ? null : obj.GetType()
.GetProperty( name )
.GetValue( obj, null );
}
}
Vous pouvez également consulter Dynamic LINQ dans la [bibliothèque VS2008 Samples][1]. Vous pourriez utiliser l'extension IEnumerable pour transformer la liste en IQueryable, puis utiliser l'extension Dynamic Link OrderBy.
list = list.AsQueryable().OrderBy( sortBy + " " + sortDirection );
Réponse pour 1.:
Vous devriez être en mesure de construire manuellement un arbre d'expression qui peut être transmis à OrderBy en utilisant le nom comme chaîne. Vous pouvez également utiliser la réflexion comme suggéré dans une autre réponse, ce qui représente moins de travail.
Edit : Voici un exemple fonctionnel de construction manuelle d'un arbre d'expression. (Tri sur X.Value, en ne connaissant que le nom "Value" ; de la propriété). Vous pourriez (devriez) construire une méthode générique pour le faire.
using System;
using System.Linq;
using System.Linq.Expressions;
class Program
{
private static readonly Random rand = new Random();
static void Main(string[] args)
{
var randX = from n in Enumerable.Range(0, 100)
select new X { Value = rand.Next(1000) };
ParameterExpression pe = Expression.Parameter(typeof(X), "value");
var expression = Expression.Property(pe, "Value");
var exp = Expression.Lambda<Func<X, int>>(expression, pe).Compile();
foreach (var n in randX.OrderBy(exp))
Console.WriteLine(n.Value);
}
public class X
{
public int Value { get; set; }
}
}
Pour construire un arbre d'expression, il faut cependant connaître les types correspondants. Cela peut ou non être un problème dans votre scénario d'utilisation. Si vous ne savez pas sur quel type vous devez faire le tri, il sera probablement plus facile d'utiliser la réflexion.
Réponse pour 2.:
Oui, puisque Comparer