我一直在玩功能<>有一段時間了,我已經設法避免它(現在)。但是,現在看來我無法永遠躲避它。例如,我嘗試了動態Linq,但幾乎所有的東西都是按照Func <>。我試過我的一本書(C#2008/Deitel & Deitel)和MSDN,但我還沒有得到它。他們全都直奔主題。簡而言之,關於Func有什麼可說的呢?
- 什麼,可Func鍵<說(在幾句話)>
- 我可以得到網頁,可以讓我開始對這個問題的一些鏈接?
感謝您的幫助
我一直在玩功能<>有一段時間了,我已經設法避免它(現在)。但是,現在看來我無法永遠躲避它。例如,我嘗試了動態Linq,但幾乎所有的東西都是按照Func <>。我試過我的一本書(C#2008/Deitel & Deitel)和MSDN,但我還沒有得到它。他們全都直奔主題。簡而言之,關於Func有什麼可說的呢?
感謝您的幫助
Func<>
是一個通用委託 - 它使用起來非常方便,因爲您不必爲每個參數/返回類型組合創建自己的委託。
在前面,你必須寫一樣的東西:
public delegate long MyDelegate(int number);
public void Method(IEnumerable<int> list, MyDelegate myDelegate)
{
foreach(var number in list)
{
myDelegate(number);
}
}
你不得不發佈您的委託,以便用戶能夠正確地調用你的方法。特別是當你需要一堆不同的委託時,你最終爲每個參數列表和返回類型發佈一個。
隨着Func<>
你只寫:
public void Method(IEnumerable<int> list, Func<int, long> myDelegate)
{
foreach(var number in list)
{
myDelegate(number);
}
}
這意味着相同的第一代碼示例 - Func<int, long>
限定代表,它有一個整數參數,並返回一個長值。
當然你也可以使用更長的參數列表,太:Func<int, int, bool, long>
仍然會返回一個長價值,同時它有兩個整數和布爾值。如果您想要一個沒有返回值的代表,您將不得不使用Action<>
,它將有void作爲返回類型。
EDIT(由請求):如何調用該方法在我的例子:
對於呼叫者,存在與MyDelegate
或Func<>
溶液之間沒有差別。在這兩種情況下,他有三個選擇要調用的方法:
使用Lambda符號(C#要求3.0,可能是短期的方法最好的解決方案):
Method(myList, i => i * i);
通過使用匿名方法(C#2。需要0):
Method(myList, delegate(int i)
{
return i * i;
});
,或者使用一個真正的方法作爲參數:
Method(myList, Square);
private static long Square(int number)
{
return number * number;
}
Func<...>
是家族委託類型,返回一些值,並採取一些參數;例如:
Func<int,bool>
僅僅是一些把一個int和返回一個布爾(返回總是在端部);例如謂詞:
int[] data = {1,2,3,4,5};
var odd = data.Where(i => i % 2 == 0);
Func<string>
是返回字符串的方法,如() => "hello world";
。
Func<DateDtime, TimeSpan, DateTime>
可能是這樣的(when,howLong) => when + howLong;
同樣有Action<...>
這不相同,但沒有返回類型。
Func<...>
沒有什麼魔力 - 它只是表達代表的一種更簡單的方式,而a:使用泛型(對LINQ很有用),或者b:不需要你查找參數是什麼;如果代表類型是模糊的(例如PipeStreamImpersonationWorker
),可能很難知道需要什麼;如果表示爲可比較的Action
,則很明顯它不需要參數並返回void
。
Func < ...,T>是委託人。 其中T是返回類型,其他所有參數都是輸入參數。
Func<int>
(例如)是一種類型(string
是一種類型)。所以你用它來聲明變量,字段,參數等等。
它表示了,只要你問它的答案需要完成的計算:
Func<int> f =() => DateTime.Now.Second;
// elsewhere...
Console.WriteLine(f());
注意如何你可以調用它就像一個方法。有許多重載版本的Func
來支持不同數量的參數。最後一個類型參數是返回類型。
Func<int, string> quoteInt = n => "\"" + n + "\"";
Console.WriteLine(quoteInt(3));
Func
是委託類型。你可以申報你自己的,但使用Func
更容易。要返回void
的位置,請使用Action
而不是Func
。如果您需要out
或ref
參數,則只需聲明自定義代表。
將lambda分配給Func
時,可以引用局部變量。這是非常強大的;這意味着Func
不僅僅是代碼;它有數據。所以它就像一個具有單一方法的對象(在技術上它是 - 該方法被稱爲Invoke
,編譯器在您調用委託時隱式調用該方法)。
語法() =>
可以放在任何表達式之前,以表示「現在不要執行此操作,將其延遲至以後」。它允許你初始化一個捕獲延遲計算的委託。然後可以在代理之後放置語法()
以實際觸發計算。所以後綴()
是前綴() =>
的一種。
+1表示一個簡潔的解釋。 – 2010-04-18 09:49:57
如果您曾經在c#中使用過=>運算符,並且您可能已經使用了,那麼您已經使用了Funcs。你只是沒有明確地宣佈它們。
所以,如果你寫這樣
var peopleWhoLikeBlue = people.Where(person => person.FavoriteColor == "Blue");
你傳遞一個Func<Person, bool>
到哪裏()方法的聲明。
如果你想羅嗦,你可以重寫像這樣的語句:
Func<Person, bool> favoriteColorIsBlue = person => person.FavoriteColor == "Blue";
var peopleWhoLikeBlue = people.Where(favoriteColorIsBlue);
,你會得到相同的結果。
Jon Skeet的關於c sharp的書籍在這方面有很好的幾章,爲什麼它對lambda函數和linq非常重要。 – 2010-04-18 10:57:29
沒有什麼可怕的,也沒有理由避免,Func或泛型委託 - 它們只是表示採用一定數量參數的常規方法的委託。 – thecoop 2010-04-18 15:40:44
你可能想看看SO上的各種Func問題:http://stackoverflow.com/questions/tagged/func – 2010-04-18 15:51:37