2011-03-22 27 views
17

Son zamanlarda lambda ifadelerine dalmakla meşgul oldum ve öğrenmek istediğim bazı özel işlevler var ama sadece başlarını veya kuyruklarını yapamadım.C# lambda ifadeleri işlev argümanları olarak

benim kodunda aşağıdaki mantığı olduğunu varsayalım: Şimdi

List<A> foo; // assuming this is populated 
string[] bar = foo.Select<A,string>(x => x.StringProperty).ToArray<string>(); 

, bir işleyici yöntem haline tüm operasyon yerine bunu böylece belki de soyut istiyorum:

string[] bar = MakeArray<A,string>(foo, x => x.StringProperty); 
int[] foobar = MakeArray<A,int>(foo, x => x.IntegerProperty); 

Bu yöntemin vücudunu yazmaktan nasıl vazgeçerim? Ben böyle bir şey olarak imza ilan olduğunu tahmin:

U[] MakeArray<T,U>(/* some lambda magic? */) where T : IEntity {} 

ama yöntem argüman olarak bir lambda ifadesi bekliyorum belirtmek için nasıl bilmiyorum ve nasıl olduğunu tam olarak yöntemin vücuda çevirir.

Yukarıdaki herhangi bir kişi bana yukarıdaki MakeArray() işlevini nasıl oluşturabilir? Eminim, nasıl yapıldığını gördüğümde, oradan alabileceğime eminim. Açıklamalarda belirttiği gibi

DÜZENLEME

, MakeArray()IEnumerable<> bir başvuru gerekli. Bunu yansıtmak için güncellendi.

+5

FWIW gibi jenerik örtük doğasını kullanabilirsiniz: Örnek işlevin imza LINQ göz atın Her ifade ile türü açıkça belirtmek zorunda kalmadan kodunuza okunabilir bir değer ekleyebilir, ancak bu öznel olabilir. Aşağıdaki ifade ilk seçiminize eşittir .. 'string [] bar = foo.Select (x => x.StringProperty) .ToArray();' –

+0

Tüm kodunuzu kullanarak dizilerinizi bulursanız, bunu yapmak isteyebilirsiniz. Bunları IEnumerable 'veya' IList 'şeklinde yeniden sınıflandırmayı düşünebilirsiniz. O zaman bunların hiçbiri gerekli olmayacaktır. Ayrıca, MakeArray'ın foo için referansa ihtiyacı yok mu? –

+0

@Quintin ~ Evet, tıpkı açıkça belirtilmiş olan jenerikler gibi (ne zaman uygulanabilir) sadece dışarı çıkardığımı net olarak görüyorum. Yine de haklısın. –

cevap

16
public static U[] MakeArray<T, U>(this IEnumerable<T> @enum, Func<T, U> rule) 
{ 
    return @enum.Select(rule).ToArray(); 
} 
+0

+1 teşekkürler! Bu cevaba, yönteme gelen Func <> parametresinin tam olarak nasıl kullanıldığını göstermek için gidiyorum. gerçek yardımsever. –

2

Action<> ve Func<>'u arıyorsunuz. Bağımsız değişken olarak lambdas geçerken

13

genellikle eşleştirme parametresi bir temsilci olmak istiyorum aşağıdaki

U[] MakeArray<T,U>(Func<T, U> projection) where T : IEntity { 
    ... 
} 

deneyin. Çoğu durumda, uygun Action<> veya Func<> değerini kullanmalısınız. Eski, geri dönen lambdalar ve ikincisi, değer verenler için.

+0

+1 teşekkürler!Özellikle açıklamaları da takdir ediyorum. –

1

Uzatma

public static class MakeArrayExtension 
{ 
    public static U[] MakeArray<T, U>(this IEnumerable<T> collection, Func<T,U> func) 
    { 
     return collection.Select(func).ToArray(); 
    } 
} 

oluşturmak Ve sonra bu

List<A> foo; // assuming this is populated 
string[] bar = foo.MakeArray<A,string>(x => x.StringProperty); 
İlgili konular