C#函數式編程中的部門運用詳解。本站提示廣大學習愛好者:(C#函數式編程中的部門運用詳解)文章只能為提供參考,不一定能成為您想要的結果。以下是C#函數式編程中的部門運用詳解正文
何謂函數式編程
信任年夜家在現實的開辟中,許多情形下完成一個功效都須要借助多個類,那末我們這裡的根本單位就是類。而函數式編程則加倍細化,導致我們處理一個功效的根本單位是函數,而不是類,每一個功效都是由多個函數組成,而且函數之間沒有直接的關系。假如簡略的文字描寫還缺乏以讓你懂得,上面我們就配以圖來演示。
以下圖所示,圖左是我們設計好的三個函數,而左邊則是我們須要完成的功效。而我們須要做的就是應用這三個函數去完成對應的三個功效,筆者在這裡只是停止簡略而又抽象的表述,現實的開辟進程能夠須要更多的函數,而且須要應用分歧的函數式編程的方法組合能力完成對應的功效。
前面我們假定F1和F2停止組合可以完勝利能G1,那末成果就以下圖所示:
對應的其他功效我們仍然是依照下面的方法停止組合便可以完成對應的功效,如許做必定有其對應的長處,對筆者而言最年夜的長處就是函數不受內部情況的影響,這裡我們不克不及與類中的辦法等量齊觀,由於辦法會遭到類高低文變量的影響,特殊是在多線程的情形下會湧現同享讀和寫的成績,而函數則不會,由於他只是經由過程參數的方法吸收內部的變量,還有一點就是復用性很強,假如後期設計的充足,在前期開辟進程中函數可以施展到最年夜的感化。說了這麼多空話,上面我們便可以開端我們的函數式編程的第一部門——部門運用。
部門運用
列位不消被這個名詞嚇壞,他重要是將我們多個參數的函數停止拆分,拆成多個只要一個參數的函數,好比上面這個函數,我們正常寫的話都是如許寫的:
Func<int, int, int> Add = (x, y) => x + y;
怎樣挪用信任筆者就不須要過量引見了,上面我們就要讓他可以或許支撐部門運用:
Func<int, Func<int, int>> Add = x => y => x + y;
這下就應當明確了吧,只是在吸收了一個值以後前往了下一個函數,然後我們再挪用這個前往的函數就完成全部挪用,我們是否是部門應用了這個函數?所以叫部門運用。上面我們來看看怎樣應用這個函數:
var Add2 = Add(2);
var result = Add2(4);
如許分紅兩行比擬輕易看懂,然則我們可以僅僅應用一行便可以了,好比上面這個方法:
var result = Add(2)(5);
哇,是否是剎時感到嵬峨上了,假如我們這個辦法的參數再多點,就是括號加括號,信任他人看到你這行代碼後就會呵呵了,然後心裡一萬個“某某”馬奔跑。
我去,看到這的人會能夠會吹捧這又沒有甚麼太特殊的器械,就是函數前往函數。對就是函數前往函數,然則現實應用起來你就會發明舒服多了,上面筆者簡略的舉一個比擬靠譜的例子來講明部門運用可以或許帶給我們甚麼,好比我們常常須要履行SQL語句,固然須要應用SqlConnection,然後附加上對應的SQL語句,為此我們可以開辟一個簡略的函數,用來簡化這一進程:
Func<SqlConnection, Func<String, DataSet>> ExecSql = x => y =>
{
using (x)
{
x.Open();
var com = x.CreateCommand();
DataSet ds = new DataSet();
com.CommandText = y;
SqlDataAdapter adapter = new SqlDataAdapter(com);
adapter.Fill(ds);
return ds;
}
};
然後挪用起來就簡略多了,我們只需傳遞給對應的SqlConnection對象,然後對應的前往值我們便可以用來履行我們的SQL語句了,詳細的應用示例以下所示:
var esql = ExecSql(new SqlConnection("xxx"));
var rds = esql("select xxxx from xxx");
rds = esql("select ffff from ffff");
然則做到這還沒有停止,面臨那些老是想出奇異成績的人,我們還有一個須要做,就是我們能夠先要傳遞SQL語句,然後再傳遞對應的SqlConnection對象,沒成績,我們專門為此寫個函數:
Func<String, Func<SqlConnection, DataSet>> ExecSqlT = x => y => ExecSql(y)(x);
我們就持續該怎樣挪用就挪用吧,然則下面都是從一開端就應用部門運用的方法來寫,現實情形能夠是曾經寫好的通俗的方法,須要轉換成部門運用的方法。那末上面我們可以本身先手動的寫幾個擴大,以便於今後的應用,起首我們來寫存在兩個參數和前往值的擴大:
public static class Functional
{
public static Func<T1, Func<T2, T3>> Currey<T1, T2, T3>(this Func<T1, T2, T3> func)
{
return x => y => func(x, y);
}
}
有了這個擴大以後我們再把下面的例子改寫:
var ExecSql = Functional.Currey<SqlConnection, String, DataSet>((x, y) =>
{
using (x)
{
x.Open();
var com = x.CreateCommand();
DataSet ds = new DataSet();
com.CommandText = y;
SqlDataAdapter adapter = new SqlDataAdapter(com);
adapter.Fill(ds);
return ds;
}
});
如許我們便可以依照我們正常的情勢來寫,然後挪用Functional的Currey便可以了,固然這裡須要顯示的傳遞泛型參數,有些情形下則不須要。
假如須要擴大更多參數的可以對應的寫下去便可以了。固然下面僅僅只是針對沒有參數的情形,我們也能夠對Action也停止擴大:
public static Func<T1, Action<T2>> Currey<T1, T2>(this Action<T1, T2> func)
{
return x => y => func(x, y);
}
到此我們就處理了將通俗函數轉換成部門運用方法的函數,然則成績就來了。假如我們一開端寫的是部門運用方法的函數,怎樣將其轉換成通俗的函數呢?天然我們還須要上面的擴大可以或許將其轉換歸去:
public static Func<T1, T2, T3> UnCurrey<T1, T2, T3>(this Func<T1, Func<T2, T3>> func)
{
return (x, y) => func(x)(y);
}