2013-05-30 12 views
45

C# ile bir lambda ifadesini bir metod çağrısında IComparer argümanı olarak geçirmek mümkün mü? Oldukça yüzden değil tahmin ediyorum derlemek için bu alamayan, ancak lambdas ve ben bir şey yapıyor olması gerekir hissediyorum anonim delegeler arasında böyle bariz bir sinerji görünüyorIComparer argümanı yerine lambda ifadesinin kullanılması

örn şey

var x = someIEnumerable.OrderBy(aClass e => e.someProperty, 
(aClass x, aClass y) => 
    x.someProperty > y.SomeProperty ? 1 : x.someProperty < y.SomeProperty ? -1 : 0); 

gibi aptalca yanlış.

TIA

+1

Olası cevap: http://stackoverflow.com/questions/9824435/interface-implementing-anonymous-class-in-c –

cevap

37

, işaret .NET 4.5 iseniz, statik yöntemini Comparer<T>.Create kullanabilirsiniz.

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); 
    } 
} 
+0

Bu dersi vermek ister misiniz? kitaplık sınıfıyla çakışmaları önlemek için farklı bir ad – Servy

+0

@Servy İyi nokta - değiştirilen –

+0

Sözdizimsel ayrıntı: Genel bir sınıfın kurucusu, sınıf adının bir parçası olan 'bölümünü içermemelidir. –

50

.NET 4.5 üzerinde iseniz, statik yöntemini Comparer<aClass>.Create kullanabilirsiniz.

Dokümantasyon: Comparer<T>.Create Method.

Örnek: Jeppe olarak

var x = someIEnumerable.OrderBy(e => e.someProperty, 
    Comparer<aClass>.Create((x, y) => x.someProperty > y.SomeProperty ? 1 : x.someProperty < y.SomeProperty ? -1 : 0) 
    ); 
+0

Ne yazık ki biz .Net 3.5 topraklarda çürüyor! TFS'yi en son sürüme yükseltmek için gereken mega-wedge'ı karşılayamazsınız :-( – haughtonomous

+2

@haughtonomous, eğer sizi geri tutan tek şeyse, TFS'yi başka bir şey lehine çevirmeyi düşündüğünüz oldu mu? –

3

tutarlı (örneğin, tek özelliği olarak) projekte anahtarları karşılaştırmak isterseniz, tüm anahtar karşılaştırma kapsüller bir sınıf tanımlayabilirsiniz:

değil, bu eşdeğer olması gereken bir uygulamasıdır kolaylık sağlamak için

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); 
    } 
} 

, bir fabrika yöntemini:

belirtilen veya varsayılan iç comparer kullanarak boş çekler, her iki nesneler üzerinde anahtar çıkarımı ve anahtar karşılaştırma dahil sizin için mantık,
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); 
    } 
} 

Sonra şöyle kullanabiliriz:

var sortedSet = new SortedSet<MyClass>(KeyComparer.Create((MyClass o) => o.MyProperty)); 

Bu uygulamanın genişletilmiş bir tartışma için benim blog post başvurabilir. Burada