2010-06-08 4 views
0

je la classe suivante définie en C#C#/LINQ: Comment définir génériquement un keySelector pour une classe basé sur un modèle avant d'appeler OrderBy

class myClass<T,U> 
{ 
    public T PropertyOne { get; set; } 
    public U PropertyTwo { get; set; } 
} 

J'ai besoin d'écrire une fonction qui réordonner une liste d'objets myClass et prend deux autres paramètres qui définissent comment faire cette réorganisation: est-ce que ma réorganisation dépend de PropertyOne ou de PropertyTwo et est-elle ascendante ou descendante? Disons que ces deux paramètres sont booléens. Avec mes connaissances actuelles dans LINQ, j'écrire:

public IList<myClass<T,U>> ReOrder(IList<myClass<T,U>> myList, bool usePropertyOne, bool ascending) 
{ 
    if (usePropertyOne) 
    { 
     if (ascending) 
     { 
      return myList.OrderBy(o => o.PropertyOne).ToList(); 
     } 
     else 
     { 
      return myList.OrderByDescending(o => o.PropertyOne).ToList(); 
     } 
    } 
    else 
    { 
     if (ascending) 
     { 
      return myList.OrderBy(o => o.PropertyTwo).ToList(); 
     } 
     else 
     { 
      return myList.OrderByDescending(o => o.PropertyTwo).ToList(); 
     } 
    } 
} 

ce qui pourrait être un moyen plus efficace/élégante de le faire? Comment puis-je déclarer l'objet Func, TResult> keySelector à réutiliser lorsque j'appelle OrderBy ou OrderByDescending? Je suis intéressant dans la réponse puisque dans ma vraie vie, je peux avoir plus de deux propriétés.

Répondre

2
public IList<T> ReOrder<T, U>(
    IList<T> myList, 
    Func<T, U> keySelector, 
    bool ascending) 
{ 
    Func<IEnumerable<T>, IEnumerable<T>> orderingFunc = 
    ascending ? 
    x => x.OrderBy(keySelector) : 
    x => x.OrderByDescending(keySelector); 

    return orderingFunc(myList).ToList(); 
} 

Si vous voulez limiter ce à MyClass seulement, vous pouvez utiliser la signature suivante:

public IList<T> ReOrder<T, U, V>(
    IList<myClass<T, U>> myList, 
    Func<myClass<T, U>, V> keySelector, 
    bool ascending) 

Si votre problème est que vous avez un bool et que vous voulez un keySelector , mais ne peut pas avoir une variable keySelector, car il devrait éventuellement retourner les deux types T et U, puis voir cette réponse: Generic Linq ordering function?

+0

avec votre nswer et le lien j'ai toutes les informations que je cherchais. Merci beaucoup! – PierrOz

1
public IList<myClass<T,U>> ReOrder(IList<myClass<T,U>> myList, Func<myClass<T,U>, object> selector, bool ascending) 
{ 
    if (ascending) 
    { 
    return myList.OrderBy(selector).ToList(); 
    } 
    else 
    { 
    return myList.OrderByDescending(selector).ToList(); 
    } 
}