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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

【IEnumerable】扩展方法的使用 C#

發(fā)布時間:2023/12/20 C# 58 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【IEnumerable】扩展方法的使用 C# 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

   直接進入主題吧...


??? ?? IEnumerable :?公開枚舉數(shù),該枚舉數(shù)支持在非泛型集合上進行簡單迭代。 好吧,迭代,我就理解成循環(huán),這些名詞真晦澀,沒意思
??? ?? 今天看的是 Using Extension Methods ,使用"擴展方法"。俺都開始看英文文檔了,得瑟中...
??? ?? 所謂擴展方法,是對類型的擴展。如對string擴展一個GotoHell(); 方法,可以這樣用? “damn”.GotoHell();
??? ?? 如何實現(xiàn)呢,咱創(chuàng)建一個新的類,叫做StringExtend,有這樣一個方法,
??? ? ? public static string GotoHell(this string str)
?? ? ? ?{
??? ? ??? ?? return str+"GotoHell";
?? ? ? ? }
??? ? ? 然后在另一處調用(同一個命名空間哦),"Damn ".GotoHell();? 輸出的值為:“Damn GotoHell” (由此看出,我心情卻是不好啊)

??? ??? 這是一般類型的擴展方法,似乎與主題那不搭邊呢,好吧,我跑題了。
??? ? ? IEnumerable 我也不管他是什么東西,反正就理解像是一個列表的東西。而實際上List是繼承的IEnumerable。
??? ? ? 為了使程序更形象,于是俺創(chuàng)建一個實體類:
?? ? ?? public class Product
???? ? {
?????? ?? public string Name { get; set; }
????? ? ? public string Category { get; set; }
????? ? ? public decimal Price { get; set; }
? ? ? }
??? ? 這兒又得跳躍一下,Using Automatically Implemented Properties。也就是public string Name{get;set;} 對應的英文定義了。
??? ? 翻譯為:自動實現(xiàn)的屬性。為啥叫自動實現(xiàn)的屬性,都實現(xiàn)了哪些呢? 如果不這樣寫,那就需要這樣:
??? ? get{ return name; } // 這里還需要創(chuàng)建一個name變量
??? ? set{ name=value;}
????? 確實比較繁瑣,耦合性也稍微高一些,同時效率也稍微低一些。
??? ? 【Tag1】現(xiàn)在我們來點數(shù)據(jù):
??? ? IEnumerable<Product> products = new List<Product> {
??????????? new Product{Name="one",Category="rose",Price=56},
??????????? new Product{Name="two",Category="jack",Price=55},
??????????? new Product{Name="three",Category="jack",Price=54}
??????????? };
??? ?? 上面說過了,IEnum... 就像是個列表的東西,List 實現(xiàn)了它,這樣賦值不足為過吧。
??? ?? 那現(xiàn)在我要篩選出 Category 為jack 的數(shù)據(jù),怎么辦呢。咱新建一個List temp ? 對吧,怕啥啊,不就浪費點內存嗎,咱有的是。
??? ?? 好吧,我以前就是這么想的,而如今,我覺得那樣做,太TM操蛋了。
??? ? ----------------------
?? ??? 我新建一個類:MyextendClass
??? ?? public static IEnumerable<Product> FilterByCategory(this IEnumerable<Product> productEnum,string categoryParam)
?? ? ? {
??? ? ? ? ? ? foreach(Product pro in productEnum)?? // 這里我習慣性寫成 foreach(var item in productEnum)
????????????? {
????????????????? if(pro.Category==categoryParam)
????????????? ? ? {
??????????????? ? ? ? yield return pro;? // yield 是什么鳥玩意兒啊? 我只知道他用在迭代器里面,告訴他這里結束了,下次你來迭代的時候往下一個迭代走。同時呢,他發(fā)現(xiàn)一個東西就立即返回過去,不要等待集合裝入完畢,據(jù)說效 率杠杠滴哦。這是我的理解,有大蝦的話,請留言更正。
?????????????????? }
?????????????? }
?? ? ? }
????? 然后,就調用了:products.FilterByCategory("jack"); 好了,這樣就獲取了 category 為 jack 的列表,你想怎么處理輸出都是你的事情了。
???? 再想想,如果我要計算jack分類的Price的總和呢?如果N多地方出現(xiàn)這種情況,難道我們都要重新寫方法嗎?話說,就算寫好了,以后也不好維護呢。好吧,咱再擴展一個唄:
public static decimal TotalPrice(this IEnumerable<Product> productEnum)
{
??? decimal total=0;
??? foreach(var item in productEnum)
??? {
?? ??? ? total+=item.Price;
?? ? }
???? return total;
}
Wonderful,這樣我們就這樣調用:products.FilterByCategory("jack").TotalPrice(); 是不是很方便,以后要修改這部分代碼頁相當方便。
只要一處擴展這個方法,到處都可以用。維護固然就很方便了。

有這么一種情況,我想按某種方式過濾出數(shù)據(jù),可是我現(xiàn)在還不知道要怎么過濾。我需要把這一層寫好先。然后有時間我再去獨立的思考那一方面的邏輯。委托? 我給你參數(shù)和我需要的返回值類型,之后你要干嘛干嘛去,我不管了(這不就是漢語中委托的意思么,呵呵)。
這里有這樣一個委托: Func<in T,out TResult> 給個T的參數(shù),返回TResult 類型的值(話說對 泛型 了解的還不夠深刻,不管亂解釋,改天我再去瞅瞅)。
好了,寫擴展方法咯:
public static IEnumerable<Product> Filter(this IEnumerable<product> productEnum,Func<Product,bool> selectorParam)
{
??? foreach(var item in productEnum){
??? ? ?? if(selectorParam(item)){
????????????? yield return item;
?? ? ? ? ?}
?? ?}
}
那委托都干了點啥呢?我們調用前給他賦予它的使命:
Func<Product,bool> categoryfilter=delegate(Product pro){? reutrn pro.Category=="rose";? };
products.Filter(categoryfilter); //終于得到rose了。
有沒有一種方式,再簡化下這種委托呢?有的,Lamada (這個我也不是很熟,改天一并看了吧):
Func<Product,bool> categoryfilter=pro=>pro.Category=="rose";
(好吧,關于擴展方法我就看了這么些,輸出結果為 兩個 “jack” ,一個 “rose” . 這男女比例真的失衡了,這咋分啊。? ??)

最后提一句,在【Tag1】的時候,IEnumerable 也可以寫成 IList 或 其他類似的 繼承了 IEnumerable 的類型或接口。

通過使用 IEnumerable 可以定制適合自己開發(fā)過程中的基本邏輯,就像PS中錄制動作一般,相當使用。

又如一個例子:假設在B2C站中,商品詳情頁有商品評論,商品評論已經緩存了下來(我想這是必要的)。

        在顯示評價時,有這樣的需求,如果是置頂?shù)膭t排在最前面,其次是精華評論,再者就是其他。

        方案a.我們可以使用正常的邏輯去處理,整出幾十行代碼。如果在其他使用類似的邏輯,只是過濾條件變了,我們又得重新寫這部分的邏輯。

        方案b.如果我們新建一個擴展類,將這部分邏輯添加到擴展中。只需業(yè)務邏輯中添加幾行代碼便可實現(xiàn)需求。不僅從代碼的美觀上還是在系統(tǒng)的維護上都有很大的好處。
 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace ConsoleTest
{
??? class Program
??? {
??????? static void Main(string[] args)
??????? {
??????????? IList<RefModel> list = Init();
??????????? IList<RefModel> list2 = list.Filter_Attr(r => r.IsTop == true && r.Sex == "boy").ToList();
??????????? Console.WriteLine("-------------------過濾-----------------------");
??????????? foreach (var item in list2)
??????????? {
??????????????? Console.WriteLine(item.Name + "? " + (item.IsTop ? "[T]? " : "") + (item.IsElite ? "[E]? " : "") + "[" + item.Sex + "]");
??????????? }
??????????? Console.WriteLine("-------------------重組:原順序---------------------------");
??????????? foreach (var item in list)
??????????? {
??????????????? Console.WriteLine(item.Name + "? " + (item.IsTop ? "[T]? " : "") + (item.IsElite ? "[E]? " : ""));
??????????? }
??????????? Console.WriteLine("-------------------重組:規(guī)則排序后----------------------------");
??????????? list = list.Filter_Order().ToList();
??????????? foreach (var item in list)
??????????? {
??????????????? Console.WriteLine(item.Name + "? " + (item.IsTop ? "[T]? " : "") + (item.IsElite ? "[E]? " : ""));
??????????? }
??????????? Console.ReadLine();
??????? }

??????? private static IList<RefModel> Init()
??????? {
??????????? IList<RefModel> list = new List<RefModel>(){
??????????????? new RefModel { Name = "charles", Sex = "boy", IsTop = true, IsElite = true },
??????????????? new RefModel { Name = "charles1", Sex = "girl", IsTop = true, IsElite = false },
??????????????? new RefModel { Name = "charles2", Sex = "girl", IsTop = false, IsElite = true },
??????????????? new RefModel { Name = "charles3", Sex = "boy", IsTop = false, IsElite = true },
??????????????? new RefModel { Name = "charles4", Sex = "girl", IsTop = true, IsElite = false },
??????????????? new RefModel { Name = "charles5", Sex = "girl", IsTop = false, IsElite = true },
??????????????? new RefModel { Name = "charles6", Sex = "boy", IsTop = true, IsElite = true },
??????????????? new RefModel { Name = "charles7", Sex = "girl", IsTop = true, IsElite = false },
??????????????? new RefModel { Name = "charles8", Sex = "boy", IsTop = false, IsElite = false },
??????????????? new RefModel { Name = "charles9", Sex = "girl", IsTop = true, IsElite = true },
??????????????? new RefModel { Name = "charles10", Sex = "boy", IsTop = false, IsElite = false },
??????????????? new RefModel { Name = "charles11", Sex = "boy", IsTop = false, IsElite = false },
??????????????? new RefModel { Name = "charles12", Sex = "girl", IsTop = true, IsElite = true },
??????????????? new RefModel { Name = "charles13", Sex = "boy", IsTop = false, IsElite = false },
??????????????? new RefModel { Name = "charles14", Sex = "boy", IsTop = false, IsElite = true },
??????????????? new RefModel { Name = "charles15", Sex = "girl", IsTop = true, IsElite = true },
??????????????? new RefModel { Name = "charles16", Sex = "girl", IsTop = false, IsElite = false },
??????????????? new RefModel { Name = "charles17", Sex = "boy", IsTop = true, IsElite = true },
??????????????? new RefModel { Name = "charles18", Sex = "boy", IsTop = false, IsElite = true },
??????????????? new RefModel { Name = "charles19", Sex = "girl", IsTop = true, IsElite = true },
??????????????? new RefModel { Name = "charles20", Sex = "boy", IsTop = true, IsElite = true },
??????????????? new RefModel { Name = "charles21", Sex = "boy", IsTop = false, IsElite = false },
??????????????? new RefModel { Name = "charles22", Sex = "girl", IsTop = true, IsElite = true },
??????????????? new RefModel { Name = "charles23", Sex = "boy", IsTop = true, IsElite = false },
??????????????? new RefModel { Name = "charles24", Sex = "boy", IsTop = true, IsElite = true }};
??????????? return list;
??????? }
??? }

??? public class RefModel
??? {
??????? public string Name { get; set; }
??????? public string Sex { get; set; }
??????? public bool IsTop { get; set; }
??????? public bool IsElite { get; set; }
??? }
}
using System; using System.Collections.Generic; using System.Linq; using System.Text;namespace ConsoleTest {public static class Filter{public static IEnumerable<RefModel> Filter_Attr(this IEnumerable<RefModel> list, Func<RefModel, bool> selectorParam){foreach (var item in list){if (selectorParam(item)){yield return item;}}}public static IEnumerable<RefModel> Filter_Order(this IEnumerable<RefModel> list){IList<RefModel> topList = new List<RefModel>();IList<RefModel> eliteList = new List<RefModel>();IList<RefModel> elseList = new List<RefModel>();foreach (var item in list){if (item.IsTop){topList.Add(item);//yield return item;//Tag FX }else if (item.IsElite){eliteList.Add(item);}else{elseList.Add(item);}}///Tag X Start foreach (var item in topList){yield return item;}///Tag X End foreach (var item in eliteList){yield return item;}foreach (var item in elseList){yield return item;}}} }

運行結果:(部分)

    最后如果理解 yield 的用法,那么可以將上述代碼中 Tag X 行取消注釋,并將 Tag X Start 內的代碼注釋掉,將得到相同的結果。這樣講減少一層循環(huán)。雖然效率提高的微乎其微,但卻如我博客Header所述:不積跬步無以至千里。

???????

    如對你有幫助,輕輕地東東手指,Recomend Or Comment 。 你的支持是我的不斷前行的動力。???????????????????????????? 歡迎轉載。

轉載于:https://www.cnblogs.com/shenchaoming/archive/2013/03/25/IEnumerable.html

總結

以上是生活随笔為你收集整理的【IEnumerable】扩展方法的使用 C#的全部內容,希望文章能夠幫你解決所遇到的問題。

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