亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C#函數(shù)式編程中的部分應用詳解

 更新時間:2015年01月28日 09:46:50   投稿:junjie  
這篇文章主要介紹了C#函數(shù)式編程中的部分應用詳解,本文講解了何謂函數(shù)式編程、函數(shù)式編程中的部分應用是什么、部分應用的代碼實例,需要的朋友可以參考下

何謂函數(shù)式編程

相信大家在實際的開發(fā)中,很多情況下完成一個功能都需要借助多個類,那么我們這里的基本單元就是類。而函數(shù)式編程則更加細化,致使我們解決一個功能的基本單元是函數(shù),而不是類,每個功能都是由多個函數(shù)構(gòu)成,并且函數(shù)之間沒有直接的關(guān)系。如果簡單的文字描述還不足以讓你理解,下面我們就配以圖來演示。

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

后面我們假設F1和F2進行組合可以完成功能G1,那么結(jié)果就如下圖所示:

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

部分應用

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

復制代碼 代碼如下:

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

怎么調(diào)用相信筆者就不需要過多介紹了,下面我們就要讓他能夠支持部分應用:

復制代碼 代碼如下:

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

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

復制代碼 代碼如下:

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

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

復制代碼 代碼如下:

var result = Add(2)(5);

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

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

復制代碼 代碼如下:

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;
                        }
                    };

然后調(diào)用起來就簡單多了,我們只要傳遞給對應的SqlConnection對象,然后對應的返回值我們就可以用來執(zhí)行我們的SQL語句了,具體的使用示例如下所示:

復制代碼 代碼如下:

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

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

復制代碼 代碼如下:

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

我們就繼續(xù)該怎么調(diào)用就調(diào)用吧,但是上面都是從一開始就利用部分應用的方式來寫,實際情況可能是已經(jīng)寫好的普通的方式,需要轉(zhuǎn)換成部分應用的方式。那么下面我們可以自己先手動的寫幾個擴展,以便于以后的使用,首先我們來寫存在兩個參數(shù)和返回值的擴展:

復制代碼 代碼如下:

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;
                        }
                    });

這樣我們就可以按照我們正常的形式來寫,然后調(diào)用Functional的Currey就可以了,當然這里需要顯示的傳遞泛型參數(shù),有些情況下則不需要。

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

復制代碼 代碼如下:

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

到此我們就解決了將普通函數(shù)轉(zhuǎn)換成部分應用方式的函數(shù),但是問題就來了。如果我們一開始寫的是部分應用方式的函數(shù),怎么將其轉(zhuǎn)換成普通的函數(shù)呢?自然我們還需要下面的擴展能夠?qū)⑵滢D(zhuǎn)換回去:

復制代碼 代碼如下:

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

相關(guān)文章

  • C#中HashTable的定義與使用方法

    C#中HashTable的定義與使用方法

    Hashtable是System.Collections命名空間提供的一個容器,用于處理和表現(xiàn)類似keyvalue的鍵值對,所以Hashtable可以支持任何類型的keyvalue鍵值對
    2012-12-12
  • C#實現(xiàn)讀取txt通用的方法小結(jié)

    C#實現(xiàn)讀取txt通用的方法小結(jié)

    這篇文章主要為大家詳細介紹了C#讀取txt通用的方法,兼容所有的UTF-8、Unicode(Little Endian)、BigEndianUnicode,有需要的小伙伴可以了解下
    2024-01-01
  • C#代碼操作XML進行增、刪、改操作

    C#代碼操作XML進行增、刪、改操作

    這篇文章主要為大家詳細介紹了C# 代碼操作XML進行增、刪、改操作,感興趣的小伙伴們可以參考一下
    2016-07-07
  • C#使用偽隨機數(shù)實現(xiàn)加密用戶密碼的方法

    C#使用偽隨機數(shù)實現(xiàn)加密用戶密碼的方法

    這篇文章主要介紹了C#使用偽隨機數(shù)實現(xiàn)加密用戶密碼的方法,對于開發(fā)C#會員系統(tǒng)或者程序安全問題都有一定的參考借鑒價值,需要的朋友可以參考下
    2014-07-07
  • C#類的成員之Field字段的使用

    C#類的成員之Field字段的使用

    本文主要介紹了C#類的成員之Field字段的使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-05-05
  • C#實現(xiàn)批量更改文件名稱大小寫或擴展名

    C#實現(xiàn)批量更改文件名稱大小寫或擴展名

    這篇文章主要為大家詳細介紹了如何利用C#實現(xiàn)批量更改文件名稱大小寫或擴展名的功能,文中的示例代碼講解詳細,對我們學習C#有一定的幫助,感興趣的小伙伴可以跟隨小編一起了解一下
    2022-12-12
  • C#調(diào)用sql2000存儲過程方法小結(jié)

    C#調(diào)用sql2000存儲過程方法小結(jié)

    這篇文章主要介紹了C#調(diào)用sql2000存儲過程的方法,以實例形式分別對調(diào)用帶輸入?yún)?shù)及輸出參數(shù)的存儲過程進行了詳細分析,非常具有實用價值,需要的朋友可以參考下
    2014-10-10
  • C#關(guān)鍵字async/await用法

    C#關(guān)鍵字async/await用法

    在本篇文章里小編給大家整理的是關(guān)于C#關(guān)鍵字async/await用法及相關(guān)實例,需要的朋友們學習下。
    2019-12-12
  • C#調(diào)用SQLite的方法實例分析

    C#調(diào)用SQLite的方法實例分析

    這篇文章主要介紹了C#調(diào)用SQLite的方法,較為詳細的介紹了SQLite的功能與特點,并實例分析了C#調(diào)用SQLite的相關(guān)技巧,需要的朋友可以參考下
    2015-06-06
  • 一篇文章說通C#中的異步迭代器

    一篇文章說通C#中的異步迭代器

    這篇文章主要給大家介紹了如何通過一篇文章說通C#中的異步迭代器的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-12-12

最新評論