C#函數式編程之部分應用

來源:互聯網
上載者:User

標籤:

何謂函數式編程

      相信大家在實際的開發中,很多情況下完成一個功能都需要藉助多個類,那麼我們這裡的基本單元就是類。而函數式編程則更加細化,致使我們解決一個功能的基本單元是函數,而不是類,每個功能都是由多個函數構成,並且函數之間沒有直接的關係。如果簡單的文字描述還不足以讓你理解,下面我們就配以圖來示範。

 

      如所示,圖左是我們設計好的三個函數,而右邊則是我們需要實現的功能。而我們需要做的就是利用這三個函數去完成對應的三個功能,筆者在這裡只是進行簡單而又形象的表述,實際的開發過程可能需要更多的函數,並且需要使用不同的函數式編程的方式組合才能完成對應的功能。

 

      後面我們假設F1和F2進行組合可以完成功能G1,那麼結果就如所示:

 

      對應的其他功能我們依然是按照上面的方式進行組合就可以完成對應的功能,這樣做必然有其對應的優點,對筆者而言最大的優點就是函數不受外部環境的影響,這裡我們不能與類中的方法相提並論,因為方法會受到類上下文變數的影響,特別是在多線程的情況下會出現共用讀和寫的問題,而函數則不會,因為他只是通過參數的方式接收外部的變數,還有一點就是複用性很強,如果前期設計的充分,在後期開發過程中函數可以發揮到最大的作用。說了這麼多廢話,下面我們就可以開始我們的函數式編程的第一部分——部分應用。

 

部分應用

      各位不用被這個名詞嚇壞,他主要是將我們多個參數的函數進行拆分,拆成多個只有一個參數的函數,比如下面這個函數,我們正常寫的話都是這樣寫的:

1 Func<int, int, int> Add = (x, y) => x + y;

 

 

      怎麼調用相信筆者就不需要過多介紹了,下面我們就要讓他能夠支援部分應用:

1 Func<int, Func<int, int>> Add = x => y => x + y;

      這下就應該明白了吧,只是在接收了一個值之後返回了下一個函數,然後我們再調用這個返回的函數就完成整個調用,我們是不是部分使用了這個函數?所以叫部分應用。下面我們來看看怎麼使用這個函數:

1 var Add2 = Add(2);2 var result = Add2(4);

      這樣分成兩行比較容易看懂,但是我們可以僅僅使用一行就可以了,比如下面這個方式:

1 var result = Add(2)(5);

 

      哇,是不是瞬間感覺高大上了,如果我們這個方法的參數再多點,就是括弧加括弧,相信別人看到你這行代碼後就會呵呵了,然後心裡一萬個“某某”馬奔騰。

 

      我去,看到這的人會可能會吹噓這又沒有什麼太特別的東西,就是函數返回函數。對就是函數返回函數,但是實際運用起來你就會發現舒暢多了,下面筆者簡單的舉一個比較靠譜的例子來說明部分應用能夠帶給我們什麼,比如我們經常需要執行SQL語句,當然需要使用SqlConnection,然後附加上對應的SQL語句,為此我們可以開發一個簡單的函數,用來簡化這一過程:

 1             Func<SqlConnection, Func<String, DataSet>> ExecSql = x => y => 2                     { 3                         using (x) 4                         { 5                             x.Open(); 6                             var com = x.CreateCommand(); 7                             DataSet ds = new DataSet(); 8                             com.CommandText = y; 9                             SqlDataAdapter adapter = new SqlDataAdapter(com);10                             adapter.Fill(ds);11                             return ds;12                         }13                     };

 

 

      然後調用起來就簡單多了,我們只要傳遞給對應的SqlConnection對象,然後對應的傳回值我們就可以用來執行我們的SQL語句了,具體的使用樣本如下所示:

1 var esql = ExecSql(new SqlConnection("xxx"));2 3 var rds = esql("select xxxx from xxx");4 rds = esql("select ffff from ffff");

 

 

      但是做到這還沒有結束,面對那些總是想出奇怪問題的人,我們還有一個需要做,就是我們可能先要傳遞SQL語句,然後再傳遞對應的SqlConnection對象,沒問題,我們專門為此寫個函數:

1 Func<String, Func<SqlConnection, DataSet>> ExecSqlT = x => y => ExecSql(y)(x);

 

 

      我們就繼續該怎麼調用就調用吧,但是上面都是從一開始就利用部分應用的方式來寫,實際情況可能是已經寫好的普通的方式,需要轉換成部分應用的方式。那麼下面我們可以自己先手動的寫幾個擴充,以便於以後的使用,首先我們來寫存在兩個參數和傳回值的擴充:

1     public static class Functional2     {3         public static Func<T1, Func<T2, T3>> Currey<T1, T2, T3>(this Func<T1, T2, T3> func)4         {5             return x => y => func(x, y);6         }7 }

 

 

有了這個擴充之後我們再把上面的例子改寫:

 1             var ExecSql = Functional.Currey<SqlConnection, String, DataSet>((x, y) => 2                     { 3                         using (x) 4                         { 5                             x.Open(); 6                             var com = x.CreateCommand(); 7                             DataSet ds = new DataSet(); 8                             com.CommandText = y; 9                             SqlDataAdapter adapter = new SqlDataAdapter(com);10                             adapter.Fill(ds);11                             return ds;12                         }13                     });

 

這樣我們就可以按照我們正常的形式來寫,然後調用FunctionalCurrey就可以了,當然這裡需要顯示的傳遞泛型參數,有些情況下則不需要。

 

      如果需要擴充更多參數的可以對應的寫下去就可以了。當然上面僅僅只是針對沒有參數的情況,我們也可以對Action也進行擴充:

1 public static Func<T1, Action<T2>> Currey<T1, T2>(this Action<T1, T2> func)2 {3       return x => y => func(x, y);4 }

 

 

      到此我們就解決了將普通函數轉換成部分應用方式的函數,但是問題就來了。如果我們一開始寫的是部分應用方式的函數,怎麼將其轉換成普通的函數呢?自然我們還需要下面的擴充能夠將其轉換回去:

1 public static Func<T1, T2, T3> UnCurrey<T1, T2, T3>(this Func<T1, Func<T2, T3>> func)2 {3      return (x, y) => func(x)(y);4 }

 

C#函數式編程之部分應用

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.