Ist es mit C # möglich, einen Lambda-Ausdruck als IComparer-Argument in einem Methodenaufruf zu übergeben?
zB so etwas wie
var x = someIEnumerable.OrderBy(aClass e => e.someProperty,
(aClass x, aClass y) =>
x.someProperty > y.SomeProperty ? 1 : x.someProperty < y.SomeProperty ? -1 : 0);
Ich kann das nicht ganz kompilieren, also schätze ich nicht, aber es scheint eine so offensichtliche Synergie zwischen Lambdas und anonymen Delegierten zu sein, dass ich das Gefühl habe, etwas Dummes falsch machen zu müssen.
TIA
Antworten:
Wie Jeppe betont, können Sie unter .NET 4.5 die statische Methode verwenden
Comparer<T>.Create
.Wenn nicht, ist dies eine Implementierung, die gleichwertig sein sollte:
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); } }
quelle
<T>
Teil des Klassennamens nicht enthalten .Wenn Sie mit .NET 4.5 arbeiten, können Sie die statische Methode verwenden
Comparer<aClass>.Create
.Dokumentation:
Comparer<T>.Create
Methode .Beispiel:
var x = someIEnumerable.OrderBy(e => e.someProperty, Comparer<aClass>.Create((x, y) => x.someProperty > y.SomeProperty ? 1 : x.someProperty < y.SomeProperty ? -1 : 0) );
quelle
.OrderBy
(Linq) haben beschlossen, keine Überlastung zu haben, die einen Delegierten für den Vergleich akzeptiert (wie einenComparison<TKey>
Delegierten). Sie können Ihre eigene Erweiterungsmethode erstellen, wenn Sie möchten.Wenn Sie projizierte Schlüssel konsistent vergleichen möchten (z. B. eine einzelne Eigenschaft), können Sie eine Klasse definieren, die die gesamte Schlüsselvergleichslogik für Sie kapselt, einschließlich Nullprüfungen, Schlüsselextraktion für beide Objekte und Schlüsselvergleich unter Verwendung des angegebenen oder standardmäßigen inneren Vergleicher:
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); } }
Zur Vereinfachung eine Fabrikmethode:
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); } }
Sie könnten dies dann folgendermaßen verwenden:
var sortedSet = new SortedSet<MyClass>(KeyComparer.Create((MyClass o) => o.MyProperty));
In meinem Blogbeitrag finden Sie eine ausführliche Beschreibung dieser Implementierung.
quelle