亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C# > 正文

C#函數式編程中的部分應用詳解

2020-01-24 02:09:56
字體:
來源:轉載
供稿:網友

何謂函數式編程

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

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

后面我們假設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);
}

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产97在线播放| 日韩精品免费电影| 欧美激情小视频| 国产精品福利在线观看网址| 成人有码视频在线播放| 亚洲美女又黄又爽在线观看| 91精品国产91久久久久久吃药| 欧美大片va欧美在线播放| 欧美做爰性生交视频| 欧美一二三视频| 国产女人精品视频| 国产日韩精品综合网站| 伊人成人开心激情综合网| 亚洲日本成人网| 欧美日韩亚洲精品内裤| 欧美日韩国产在线| 久久久精品一区二区三区| 国产日本欧美视频| 91在线观看免费高清完整版在线观看| 欧美激情精品久久久久| 91精品国产综合久久香蕉最新版| 一区二区三区视频观看| 国产精品丝袜一区二区三区| 日韩免费在线电影| 欧美中文字幕在线视频| 欧美黑人极品猛少妇色xxxxx| 久久91精品国产91久久久| 久久久久久久999| 深夜成人在线观看| 日韩成人久久久| 亚洲人成在线免费观看| 国产精品777| 中文字幕亚洲精品| 91国内精品久久| 日韩免费观看高清| 国产成人精品久久二区二区91| 国产97色在线|日韩| 日本精品久久久久久久| 69久久夜色精品国产69| 日韩在线免费av| 26uuu亚洲国产精品| 久久国产加勒比精品无码| 欧洲亚洲女同hd| 91欧美精品午夜性色福利在线| 欧美在线视频a| 精品成人国产在线观看男人呻吟| 国产精品一区二区三区成人| 国产97免费视| 欧美成人中文字幕| 亚洲天堂av在线免费观看| 97在线免费观看| 欧美日韩第一页| 亚洲九九九在线观看| 在线观看国产成人av片| 精品爽片免费看久久| 欧美一区二区三区免费观看| 一区二区三区高清国产| 欧美一级视频免费在线观看| 国产精品v日韩精品| 日韩美女免费线视频| 2019亚洲男人天堂| 久久精品2019中文字幕| 亚洲欧美制服综合另类| 欧美日韩国产一中文字不卡| 亚洲精品白浆高清久久久久久| 欧美国产日产韩国视频| 亚洲国产精品va在线看黑人动漫| 日韩女优人人人人射在线视频| 久久艹在线视频| 久久精品一偷一偷国产| 国产午夜精品免费一区二区三区| 欧美激情小视频| 最近2019中文免费高清视频观看www99| 欧美伦理91i| 亚洲第一级黄色片| 国产一区二区黄| 91香蕉亚洲精品| 亚洲亚裔videos黑人hd| 日韩一区二区久久久| 欧美精品久久久久久久| 欧美极品少妇xxxxⅹ免费视频| 91精品国产色综合久久不卡98| www.日本久久久久com.| 国产日韩在线亚洲字幕中文| 欧美一乱一性一交一视频| 日韩欧美中文字幕在线播放| 日韩在线观看免费| 影音先锋欧美在线资源| 欧美劲爆第一页| 久久久久久成人精品| 亚洲毛片在线观看.| 777国产偷窥盗摄精品视频| 精品亚洲一区二区三区在线观看| 亚洲国产99精品国自产| 亚洲男人天堂视频| 亚洲色图狂野欧美| 在线不卡国产精品| 日本不卡视频在线播放| 2025国产精品视频| 在线免费看av不卡| 亚洲人成人99网站| 日韩精品免费在线播放| 在线观看欧美视频| 美女少妇精品视频| 岛国av午夜精品| 视频在线观看99| 国内精品免费午夜毛片| 久久久久久久亚洲精品| 精品女同一区二区三区在线播放| 久久99热这里只有精品国产| 欧美最顶级丰满的aⅴ艳星| 国产脚交av在线一区二区| 日韩av影视在线| 国产日韩中文字幕| 日韩欧美中文在线| 久久久精品免费| 欧美大成色www永久网站婷| 92版电视剧仙鹤神针在线观看| 亚洲精品国精品久久99热一| 欧美肥老太性生活视频| 国产国语videosex另类| 国产脚交av在线一区二区| 亚洲最大的成人网| 欧美激情第6页| 91在线无精精品一区二区| 在线亚洲欧美视频| 久久偷看各类女兵18女厕嘘嘘| 美女久久久久久久久久久| 国产欧美精品在线播放| 欧美精品一本久久男人的天堂| 国产在线拍揄自揄视频不卡99| 国产999精品久久久影片官网| 亚洲精品视频在线播放| 青青精品视频播放| 国产精品久久久久久久天堂| 亚洲日韩欧美视频一区| 亚洲国产欧美精品| 亚洲午夜国产成人av电影男同| 中文字幕日韩专区| 一区二区日韩精品| 日韩在线激情视频| 久久99国产精品自在自在app| 国产精品老女人精品视频| 国产成人精品久久二区二区91| 亚洲欧美在线磁力| 久久精品久久久久久| 日韩欧美国产激情| 97国产精品人人爽人人做| 欧美亚洲免费电影| 91av在线影院| 欧美影院在线播放| 久久99精品国产99久久6尤物| 最新日韩中文字幕| 亚洲精品中文字幕女同| 国产日韩综合一区二区性色av| 欧美成人在线影院| 亚洲一区二区三区视频| 日韩在线观看网址| 国产免费一区二区三区在线能观看| 97精品国产91久久久久久| 成人中心免费视频| 欧美成年人网站| 91精品成人久久| 欧美国产精品va在线观看|