2011-03-22 731 views
17

最近我一直忙於潛入lambda表達式,還有一些特定的功能,我一直在意的是要學習,但似乎無法形成正面或反面。C#lambda表達式作爲函數參數

假設我有以下的邏輯在我的代碼:

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

現在,我想也許是抽象的是整個操作成處理方法,這樣我可以做到這一點,而不是:

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

我將如何去寫這個方法的身體?我預見聲明的簽名是這樣的:

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

,但我不知道如何指定我期待一個lambda表達式作爲方法的參數,以及如何準確翻譯成方法的主體。

任何人都可以告訴我如何創建上面的MakeArray()函數?我很確定,一旦我看到它是如何完成的,我可以從那裏拿起它。

EDIT

如在評論中指出,MakeArray()需要對IEnumerable<>的參考。更新以反映這一點。

+5

FWIW仿製藥的隱性性質可以通過不必在每個語句中明確聲明類型來爲代碼添加可讀的值,但這可能是主觀的。下面的語句等於你的第一個選擇..'string [] bar = foo.Select(x => x.StringProperty).ToArray();' – 2011-03-22 19:36:25

+0

如果你發現自己在你的代碼中使用數組,你可能想要考慮將它們重構爲'IEnumerable '或'IList '。那麼這些都不是必需的。另外,'MakeArray'不需要引用foo嗎? – 2011-03-22 19:44:52

+0

@Quintin〜是的,我有點像泛型一樣明確表示(如果適用),所以我很清楚要抽出什麼。你說的沒錯。 – 2011-03-22 19:45:43

回答

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

+1謝謝!我將用這個答案來展示如何使用方法中的Func <>參數。真正有用。 – 2011-03-22 19:44:17

2

您正在尋找Action<>Func<>

13

請嘗試以下

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

當傳遞lambda表達式作爲參數,你一般要匹配的參數是一個代表。在大多數情況下,您應該只使用適當的Action<>Func<>值。前者用於void返回的lambdas,後者用於返回值。

+0

+1謝謝!我特別欣賞這個解釋。 – 2011-03-22 19:42:39

1

您可以創建擴展

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

,然後用它像這樣

List<A> foo; // assuming this is populated 
string[] bar = foo.MakeArray<A,string>(x => x.StringProperty); 
相關問題