Est-il possible avec C # de passer une expression lambda comme argument IComparer dans un appel de méthode?
par exemple quelque chose comme
var x = someIEnumerable.OrderBy(aClass e => e.someProperty,
(aClass x, aClass y) =>
x.someProperty > y.SomeProperty ? 1 : x.someProperty < y.SomeProperty ? -1 : 0);
Je n'arrive pas à faire compiler cela, donc je suppose que non, mais il semble qu'une synergie si évidente entre lambdas et les délégués anonymes que je pense que je dois faire quelque chose de stupidement mauvais.
TIA
Comme le souligne Jeppe, si vous êtes sur .NET 4.5, vous pouvez utiliser la méthode statique Comparer<T>.Create
.
Sinon, c'est une implémentation qui devrait être équivalente:
public class FunctionalComparer<T> : IComparer<T>
{
private Func<T, T, int> comparer;
public FunctionalComparer(Func<T, T, int> comparer)
{
this.comparer = comparer;
}
public static IComparer<T> Create(Func<T, T, int> comparer)
{
return new FunctionalComparer<T>(comparer);
}
public int Compare(T x, T y)
{
return comparer(x, y);
}
}
Si vous êtes sur .NET 4.5, vous pouvez utiliser la méthode statique Comparer<aClass>.Create
.
Documentation: Comparer<T>.Create
Méthode .
Exemple:
var x = someIEnumerable.OrderBy(e => e.someProperty,
Comparer<aClass>.Create((x, y) => x.someProperty > y.SomeProperty ? 1 : x.someProperty < y.SomeProperty ? -1 : 0)
);
Si vous souhaitez systématiquement comparer les clés projetées (comme une seule propriété), vous pouvez définir une classe qui encapsule pour vous toute la logique de comparaison de clés, y compris les vérifications nulles, l'extraction de clés sur les deux objets et la comparaison de clés à l'aide de l'intérieur spécifié ou par défaut comparateur:
public class KeyComparer<TSource, TKey> : Comparer<TSource>
{
private readonly Func<TSource, TKey> _keySelector;
private readonly IComparer<TKey> _innerComparer;
public KeyComparer(
Func<TSource, TKey> keySelector,
IComparer<TKey> innerComparer = null)
{
_keySelector = keySelector;
_innerComparer = innerComparer ?? Comparer<TKey>.Default;
}
public override int Compare(TSource x, TSource y)
{
if (object.ReferenceEquals(x, y))
return 0;
if (x == null)
return -1;
if (y == null)
return 1;
TKey xKey = _keySelector(x);
TKey yKey = _keySelector(y);
return _innerComparer.Compare(xKey, yKey);
}
}
Pour plus de commodité, une méthode d'usine:
public static class KeyComparer
{
public static KeyComparer<TSource, TKey> Create<TSource, TKey>(
Func<TSource, TKey> keySelector,
IComparer<TKey> innerComparer = null)
{
return new KeyComparer<TSource, TKey>(keySelector, innerComparer);
}
}
Vous pouvez alors utiliser ceci comme ceci:
var sortedSet = new SortedSet<MyClass>(KeyComparer.Create((MyClass o) => o.MyProperty));
Vous pouvez vous référer à mon article de blog pour une discussion approfondie de cette implémentation.