日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > C# >内容正文

C#

【More Effective C#】LINQ表达式与方法调用的映射

發(fā)布時(shí)間:2024/8/22 C# 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【More Effective C#】LINQ表达式与方法调用的映射 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

LINQ構(gòu)建在兩個(gè)概念之上,一種查詢(xún)語(yǔ)言和一系列將查詢(xún)語(yǔ)言轉(zhuǎn)換成方法調(diào)用的實(shí)現(xiàn).在編譯時(shí),編譯器將LINQ表達(dá)式(LINQ?to?object)轉(zhuǎn)換成方法調(diào)用.

.Net基礎(chǔ)類(lèi)庫(kù)提供了兩種擴(kuò)展方法.System.Linq.Enumerable使用了IEnumerable<T>上擴(kuò)展來(lái)實(shí)現(xiàn),System.Linq.Queryable則提供了類(lèi)似的一系列IQueryable<T>上的擴(kuò)展.兩者的轉(zhuǎn)換略為不同.前者在編譯時(shí)轉(zhuǎn)換成相應(yīng)的擴(kuò)展方法調(diào)用.而后者則能將LINQ表達(dá)式轉(zhuǎn)換成SQL查詢(xún),并有SQL數(shù)據(jù)庫(kù)引擎執(zhí)行.

LINQ表達(dá)式到方法調(diào)用的轉(zhuǎn)換時(shí)一個(gè)復(fù)雜的迭代過(guò)程.編譯器在轉(zhuǎn)換時(shí)也有一個(gè)特定的順序.

例如

?int[]?someNumbers?=?{?0,?1,?2,?3,?4,?5,?6,?7,?8,?9?};

????????????var?answer?=?from?n?in?someNumbers

?????????????????????????where?n?<?5

?????????????????????????select?n;

最后將轉(zhuǎn)換成

int[]?someNumbers?=?{?0,?1,?2,?3,?4,?5,?6,?7,?8,?9?};

????????????var?answer?=someNumbers.Where(n=>n<5);

可以看到.在上面的轉(zhuǎn)換后.Select被優(yōu)化去掉了.這就是一個(gè)退化選擇.不止是Where和Select.相應(yīng)的LINQ表達(dá)式都會(huì)被轉(zhuǎn)換成相應(yīng)的擴(kuò)展方法..

編譯器的轉(zhuǎn)換

C#編譯器將把查詢(xún)和lambda表達(dá)式(Linq?to?object)轉(zhuǎn)換成靜態(tài)委托,實(shí)力委托和閉包.

int[]?someNumbers?=?{?0,?1,?2,?3,?4,?5,?6,?7,?8,?9?};

????????????var?answer?=?from?n?in?someNumbers

?????????????????????????select?n;

把上邊的代碼編譯.使用Refletor打開(kāi)程序集.查看生成的相關(guān)代碼.

?int[]?someNumbers?=?new?int[]?{?0,?1,?2,?3,?4,?5,?6,?7,?8,?9?};

????if?(CS$<>9__CachedAnonymousMethodDelegate1?==?null)

????{

????????CS$<>9__CachedAnonymousMethodDelegate1?=?new?Func<int,?int>(null,?(IntPtr)?<Main>b__0);

????}

????IEnumerable<int>?answer?=?Enumerable.Select<int,?int>(someNumbers,?CS$<>9__CachedAnonymousMethodDelegate1);

可以看到.編譯器自動(dòng)生成了一個(gè)委托.下面.使用更為直觀的代碼描述.生成的代碼大致如下:

?private?static?int?HiddenFuc(int?n)

????????{

????????????return?n?*?n;

????????}

????????private?static?Func<int,?int>?HiddenDelegateDefinition

?int[]?someNumbers?=?new?int[]?{?0,?1,?2,?3,?4,?5,?6,?7,?8,?9?};

????????????if?(HiddenDelegateDefinition?==?null)

????????????{

????????????????HiddenDelegateDefinition?=?new?Func<int,?int>(HiddenFuc);

????????????}

????????????IEnumerable<int>?anser?=?someNumbers.Select<int,?int>(HiddenDelegateDefinition);

可以看到.編譯器生成了一個(gè)靜態(tài)方法實(shí)現(xiàn)Select表達(dá)式.并且通過(guò)委托實(shí)現(xiàn)查詢(xún).

實(shí)際上.上述的lambda表達(dá)式的主體部分并沒(méi)有訪問(wèn)任何實(shí)例變量或是局部變量.什么是實(shí)例變量.什么又是局部變量.?

訪問(wèn)實(shí)例變量的Lambe表達(dá)式

public?class?ModFilter

????{

????????private?readonly?int?modulus;

????????public?ModFilter(int?mod)

????????{

????????????modulus?=?mod;

????????}

????????public?IEnumerable<int>?FindValues(IEnumerable<int>?sequence)

????????{

????????????return?from?n?in?sequence

???????????????????where?n?%?modulus?==?0???//訪¤問(wèn)實(shí)例變量

???????????????????select?n?*?n;

????????}

????}

編譯器將會(huì)為你生成一個(gè)實(shí)例方法,生成的代碼大致如下

?public?class?ModFilter

????{

????????private?readonly?int?modulus;

????????public?ModFilter(int?mod)

????????{

????????????modulus?=?mod;

????????}

????????private?bool?WhereClause(int?n)

????????{

????????????return?(n?%?modulus)?==?0;

????????}

????????private?static?int?SelectClause(int?n)

????????{

????????????return?n?*?n;

????????}

????????private?static?Func<int,?int>?SelectDelegate;

????????public?IEnumerable<int>?FindValues(IEnumerable<int>?sequence)

????????{

????????????if?(SelectDelegate?==?null)

????????????{

????????????????SelectDelegate?=?new?Func<int,?int>(SelectClause);

????????????}

????????????return?sequence.Where<int>(new?Func<int,?bool>(this.WhereClause)).Select<int,?int>(SelectClause);

????????}

}

Lambda表達(dá)式訪問(wèn)實(shí)例變量

? 若是Lambda表達(dá)式中訪問(wèn)了外部方法的實(shí)例變量.則編譯器將自動(dòng)生成一個(gè)私有的嵌套類(lèi)型.

public?class?ModFilterCloser

????{

????????private?readonly?int?modulus;

????????public?ModFilterCloser(int?mod)

????????{

????????????modulus?=?mod;

????????}

????????public?IEnumerable<int>?FindValues(IEnumerable<int>?sequence)

????????{

????????????int?numValues?=?0;

????????????return?from?n?in?sequence

???????????????????where?n?%?modulus?==?0

???????????????????select?n?*?n?/?++numValues;?//調(diào)用了方法外的局部變量numValues

????????}

????}

生成的代碼大致如下.

?public?class?ModFilterCloser

????{

????????private?sealed?class?Closure

????????{

????????????public?ModFilterCloser?outer;

????????????public?int?numValues;

????????????public?int?SelectClause(int?n)

????????????{

????????????????return?(n?*?n)?/?++this.numValues;

????????????}

????????}

????????private?readonly?int?modulus;

????????public?ModFilterCloser(int?mod)

????????{

????????????modulus?=?mod;

????????}

????????private?bool?WhereClause(int?n)

????????{

????????????return?(n?%?modulus)?==?0;

????????}

????????public?IEnumerable<int>?FindValues(IEnumerable<int>?sequence)

????????{

????????????Closure?c?=?new?Closure();

????????????c.outer?=?this;

????????????c.numValues?=?0;

????????????return?sequence.Where<int>(new?Func<int,bool>(this.WhereClause)).Select<int,int>(c.SelectClause));

????????}

????}

LINQ?to?Sql?的實(shí)現(xiàn)

最后.要注意到.以上的轉(zhuǎn)換實(shí)現(xiàn)都是在Linq?to?object中實(shí)現(xiàn).IEnumberale<T>.LINQ?to?SQL?的轉(zhuǎn)換.編譯后可以看到.并沒(méi)發(fā)生任何變化.那是因?yàn)?/font>.只有在遍歷迭代時(shí),延遲執(zhí)行.LINQ?to?SQL?Provider才將LINQ表達(dá)式轉(zhuǎn)換成SQL查詢(xún).

轉(zhuǎn)載于:https://www.cnblogs.com/kongyiyun/archive/2010/10/15/1851866.html

總結(jié)

以上是生活随笔為你收集整理的【More Effective C#】LINQ表达式与方法调用的映射的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。