Func<T1, T2, TResult> 委托
封裝一個具有兩個參數並返回 TResult 參數指定的類型值的方法。
語法
public delegate TResult Func<in T1, in T2, out TResult>( T1 arg1, T2 arg2 )
類型參數 in T1 此委托封裝的方法的第一個參數類型。 該類型參數是逆變。即可以使用指定的類型或派生程度更低的類型。有關協變和逆變的更多信息,請參見泛型中的協變和逆變。 in T2 此委托封裝的方法的第二個參數類型。 out TResult 此委托封裝的方法的返回值類型。 該類型參數是協變。即可以使用指定的類型或派生程度更高的類型。有關協變和逆變的更多信息,請參見泛型中的協變和逆變。 參數 arg1類型:T1 此委托封裝的方法的第一個參數。 arg2類型:T2 此委托封裝的方法的第二個參數。 返回值 類型:TResult 此委托封裝的方法的返回值。
備注
可以使用此委托表示一種能以參數形式傳遞的方法,而不用顯式聲明自定義委托。封裝的方法必須與此委托定義的方法簽名相對應。也就是說,封裝的方法必須具有兩個均通過值傳遞給它的參數,並且必須返回值。
若要引用具有兩個參數並返回 void 的方法(或者要在 Visual Basic 中引用被聲明為 Sub 而不是被聲明為 Function 的方法),請改用泛型 Action<T1, T2> 委托。
在使用 Func<T1, T2, TResult> 委托時,不必顯式定義一個封裝具有兩個參數的方法的委托。例如,以下代碼顯式聲明了一個名為 ExtractMethod 的委托,並將對 ExtractWords 方法的引用分配給其委托實例。
示例
下面的示例演示如何聲明和使用 Func<T1, T2, TResult> 委托。此示例聲明一個 Func<T1, T2, TResult> 變量,並將其分配給一個采用 String 值和 Int32 值作為參數的 lambda 表達式。如果 String 參數的長度等於 Int32 參數的值,則此 lambda 表達式將返回 true。隨后在查詢中使用封裝此方法的委托來篩選字符串數組中的字符串。

using System; using System.Collections.Generic; using System.Linq; public class Func3Example { public static void Main() { Func<String, int, bool> predicate = (str, index) => str.Length == index; String[] words = { "orange", "apple", "Article", "elephant", "star", "and" }; IEnumerable<String> aWords = words.Where(predicate).Select(str => str); foreach (String word in aWords) Console.WriteLine(word); } }
了解完這些以后,我們來看看它的應用。
不知道童鞋們有沒有遇到這樣的問題,在讀取數據訪問層中數據集合時,發現該方法需要返回的結果中包括對象及其外鍵對象時,又不想添加一個實體類來封裝它,那么有什么別的好辦法嗎?也許您會選擇用動態對象(dynamic關鍵字),不錯,這個這確實可以解決這個問題,但是有一個弊端,且不論動態對象在運行時編譯,在編寫程序時,它存在一個很不方便的體驗,它不能點(.)出它的屬性,不免產生意外的拼寫錯誤或是尋找-復制-黏貼的麻煩。
那么怎么辦呢?我們可以利用Func<T1, T2, TResult> 委托來幫助我們實現。

public IEnumerable<TResult> GetAllUser<TResult>(Func<User, Person, TResult> itemFactory) { var results = from u in User join p in Person on u.Id equals p.uId select new { User = u, Person = p }; IList<TResult> resultItems = new List<TResult>(); foreach (var item in results.ToList()) { resultItems.Add(itemFactory(item.User, item.Person)); } return resultItems; }

var query = userDao.GetAllUser((u, p) => { return new { u.Id, u.LoginName, pId = p.Id, p.Name }; });
此外,當然也可以自定義更多的委托,這里筆者就不詳細介紹了,讀者可自行嘗試。
哈哈,這樣是否有幫到您呢?本人文筆粗糙簡陋,請多多大蝦們指教!