【C#2.0】发挥匿名委托的威力!
生活随笔
收集整理的這篇文章主要介紹了
【C#2.0】发挥匿名委托的威力!
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
這幾天研究了一下Linq,C# 3.0中的“擴展方法”特性為IEnumerable<T>增加了諸如Where、Select等查詢方法,這使得“語言集成查詢”成為順其自然的事情。而C#3.0中Linq的實現(xiàn)也是建立在C#2.0的匿名委托的特性之上。
???今天,我嘗試在C#2.0中使用匿名委托模擬C#3.0中Where、Select等查詢方法的實現(xiàn)。我將所有的查詢方法作為靜態(tài)方法在GenericHepler靜態(tài)類中實現(xiàn)。
???之前,我們先定義泛型委托:
???public?delegate?TResult?Func<T,?TResult>(T?source); ???這個委托在后面的實現(xiàn)中需要用到。
???作為基礎(chǔ),首先,我們需要實現(xiàn)ForSpecification方法,該方法的含義是:對集合中滿足指定條件的元素執(zhí)行指定方法調(diào)用。
?????????///?<summary>
????????///?ForSpecification?對集合中滿足predicate條件的元素執(zhí)行action。如果沒有條件,predicate傳入null。
????????///?</summary>???????
????????public?static?void?ForSpecification<TSource>(IEnumerable<TSource>?collection,?Action<TSource>?action,?Predicate<TSource>?predicate)
????????{
????????????if?(predicate?==?null)
????????????{
????????????????foreach?(TSource?obj?in?collection)
????????????????{
????????????????????action(obj);
????????????????}
????????????????return;
????????????}
????????????foreach?(TSource?obj?in?collection)
????????????{
????????????????if?(predicate(obj))
????????????????{
????????????????????action(obj);
????????????????}
????????????}
????????}
???有了ForSpecification的實現(xiàn),我們就可以在其基礎(chǔ)上實現(xiàn)ForEach和ForFirstSpecification:
???????#region?ForEach
????????///?<summary>
????????///?ForEach??對集合中的每個元素執(zhí)行action。
????????///?</summary>????????
????????public?static?void?ForEach<TSource>(IEnumerable<TSource>?collection,?Action<TSource>?action)
????????{
????????????GenericHepler.ForSpecification<TSource>(collection,?action,?null);
????????}
????????#endregion
????????#region?ForFirstSpecification
????????///?<summary>
????????///?ForSpecification?對集合中第一個滿足predicate條件的元素執(zhí)行action。如果沒有條件,predicate傳入null。
????????///?</summary>???????
????????public?static?void?ForFirstSpecification<TSource>(IEnumerable<TSource>?collection,?Action<TSource>?action,?Predicate<TSource>?predicate)
????????{
????????????if?(predicate?==?null)
????????????{
????????????????foreach?(TSource?obj?in?collection)
????????????????{
????????????????????action(obj);
????????????????????break;
????????????????}
????????????}
????????????else
????????????{
????????????????foreach?(TSource?obj?in?collection)
????????????????{
????????????????????if?(predicate(obj))
????????????????????{
????????????????????????action(obj);
????????????????????????break;
????????????????????}
????????????????}
????????????}
????????}
????????#endregion
???有了ForSpecification,我們就可以實現(xiàn)查詢方法Where:
???????#region?Where
????????///?<summary>
????????///?Where?從集合中選取符合條件的元素
????????///?</summary>???????
????????public?static?IList<TSource>?Where<TSource>(IEnumerable<TSource>?source,?Predicate<TSource>?predicate)
????????{www.elivn.com
????????????IList<TSource>?list?=?new?List<TSource>();
????????????GenericHepler.ForSpecification(source,?delegate(TSource?ele)?{?list.Add(ele);?}?,?predicate);
????????????return?list;
????????}?
????????#endregion ???對于C#3.0中的Select方法,其實現(xiàn)需要匿名類型的支持,而C#2.0中不支持匿名類型,所以,我用泛型來代替。我使用ConvertSpecification來模擬Select實現(xiàn):
???????#region?ConvertSpecification
????????///?<summary>
????????///?ConvertSpecification?將source中的符合predicate條件元素轉(zhuǎn)換為TResult類型
????????///?</summary>???????
????????public?static?IList<TResult>?ConvertSpecification<TSource,?TResult>(IEnumerable<TSource>?source,?Func<TSource,?TResult>?converter,?Predicate<TSource>?predicate)
????????{
????????????IList<TResult>?list?=?new?List<TResult>();
????????????GenericHepler.ForSpecification<TSource>(source,?delegate(TSource?ele)?{?list.Add(converter(ele));?}?,predicate);
????????????return?list;
????????}
????????#endregion ???converter委托用于從TSource類型對象構(gòu)造TResult類型的對象。
???有了ConvertSpecification實現(xiàn),我們就可以在其上繼續(xù)實現(xiàn)ConvertAll和ConvertFirstSpecification:
???????#region?ConvertAll
????????///?<summary>
????????///?ConvertAll?將source中的每個元素轉(zhuǎn)換為TResult類型
????????///?</summary>???????
????????public?static?IList<TResult>?ConvertAll<TSource,?TResult>(IEnumerable<TSource>?source,?Func<TSource,?TResult>?converter)
????????{
????????????return?GenericHepler.ConvertSpecification<TSource,?TResult>(source,?converter,?null);
????????}
????????#endregion
????????#region?ConvertFirstSpecification
????????///?<summary>
????????///?ConvertSpecification?將source中的符合predicate條件的第一個元素轉(zhuǎn)換為TResult類型
????????///?</summary>???????
????????public?static?TResult?ConvertFirstSpecification<TSource,?TResult>(IEnumerable<TSource>?source,?Func<TSource,?TResult>?converter,?Predicate<TSource>?predicate)
????????{
????????????TSource?target?=?GenericHepler.GetFirstSpecification<TSource>(source,?predicate);
????????????if?(target?==?null)
????????????{
????????????????return?default(TResult);
????????????}
????????????return?converter(target);
????????}
????????#endregion??????? ???有了上面的基礎(chǔ),我們還可以實現(xiàn)ContainsSpecification方法:
???????#region?ContainsSpecification
????????///?<summary>
????????///?ContainsSpecification?集合中是否包含滿足predicate條件的元素。
????????///?</summary>???????
????????public?static?bool?ContainsSpecification<TSource>(IEnumerable<TSource>?source,?Predicate<TSource>?predicate,?out?TSource?specification)
????????{
????????????specification?=?default(TSource);
????????????foreach?(TSource?element?in?source)
????????????{
????????????????if?(predicate(element))
????????????????{
????????????????????specification?=?element;
????????????????????return?true;
????????????????}
????????????}
????????????return?false;
????????}
????????#endregion????????
????????#region?ContainsSpecification
????????///?<summary>
????????///?ContainsSpecification?集合中是否包含滿足predicate條件的元素。
????????///?</summary>???????
????????public?static?bool?ContainsSpecification<TSource>(IEnumerable<TSource>?source,?Predicate<TSource>?predicate)
????????{
????????????TSource?specification;
????????????return?GenericHepler.ContainsSpecification<TSource>(source,?predicate,?out?specification);
????????}?
????????#endregion???????
????????{
????????????IList<string>?results?=?new?List<string>();
????????????foreach?(IPlayer?player?in?this.playerList)
????????????{
????????????????if?(player.Age?>?30)
????????????????{
????????????????????results.Add(player.ID);
????????????????}
????????????}
????????????return?results;
????????}
?{
?????return?GenericHepler.ConvertSpecification<IPlayer,?string>(this.playerList,?delegate(IPlayer?player)?{?return?player.ID;?}?,?delegate(IPlayer?player)?{return?player.Age?>?30?});????????????
?}
????????{
????????????IList<IPlayer>?partnersList?=?new?List<IPlayer>();
????????????foreach?(string?userID?in?this.dicPlayers.Keys)
????????????{
????????????????bool?exclude?=?false;
????????????????foreach?(string?excludedUser?in?excludedUserIDs)
????????????????{
????????????????????if?(userID?==?excludedUser)
????????????????????{
????????????????????????exclude?=?true;
????????????????????????break;
????????????????????}
????????????????}
????????????????if?(!exclude)
????????????????{
????????????????????partnersList.Add(this.dicPlayers[userID]);
????????????????}
????????????}
????????????return?partnersList;?
????????}
?{
?????return?GenericHepler.Where<IPlayer>(this.dicPlayers.Values,?delegate(IPlayer?player)?{?return?!GenericHepler.ContainsSpecification<string>(excludedUserIDs,?delegate(string?id)?{?return?id?==?player.UserID;?});?});????????????????????????????
?}
???今天,我嘗試在C#2.0中使用匿名委托模擬C#3.0中Where、Select等查詢方法的實現(xiàn)。我將所有的查詢方法作為靜態(tài)方法在GenericHepler靜態(tài)類中實現(xiàn)。
???之前,我們先定義泛型委托:
???public?delegate?TResult?Func<T,?TResult>(T?source); ???這個委托在后面的實現(xiàn)中需要用到。
???作為基礎(chǔ),首先,我們需要實現(xiàn)ForSpecification方法,該方法的含義是:對集合中滿足指定條件的元素執(zhí)行指定方法調(diào)用。
?????????///?<summary>
????????///?ForSpecification?對集合中滿足predicate條件的元素執(zhí)行action。如果沒有條件,predicate傳入null。
????????///?</summary>???????
????????public?static?void?ForSpecification<TSource>(IEnumerable<TSource>?collection,?Action<TSource>?action,?Predicate<TSource>?predicate)
????????{
????????????if?(predicate?==?null)
????????????{
????????????????foreach?(TSource?obj?in?collection)
????????????????{
????????????????????action(obj);
????????????????}
????????????????return;
????????????}
????????????foreach?(TSource?obj?in?collection)
????????????{
????????????????if?(predicate(obj))
????????????????{
????????????????????action(obj);
????????????????}
????????????}
????????}
???有了ForSpecification的實現(xiàn),我們就可以在其基礎(chǔ)上實現(xiàn)ForEach和ForFirstSpecification:
???????#region?ForEach
????????///?<summary>
????????///?ForEach??對集合中的每個元素執(zhí)行action。
????????///?</summary>????????
????????public?static?void?ForEach<TSource>(IEnumerable<TSource>?collection,?Action<TSource>?action)
????????{
????????????GenericHepler.ForSpecification<TSource>(collection,?action,?null);
????????}
????????#endregion
????????#region?ForFirstSpecification
????????///?<summary>
????????///?ForSpecification?對集合中第一個滿足predicate條件的元素執(zhí)行action。如果沒有條件,predicate傳入null。
????????///?</summary>???????
????????public?static?void?ForFirstSpecification<TSource>(IEnumerable<TSource>?collection,?Action<TSource>?action,?Predicate<TSource>?predicate)
????????{
????????????if?(predicate?==?null)
????????????{
????????????????foreach?(TSource?obj?in?collection)
????????????????{
????????????????????action(obj);
????????????????????break;
????????????????}
????????????}
????????????else
????????????{
????????????????foreach?(TSource?obj?in?collection)
????????????????{
????????????????????if?(predicate(obj))
????????????????????{
????????????????????????action(obj);
????????????????????????break;
????????????????????}
????????????????}
????????????}
????????}
????????#endregion
???有了ForSpecification,我們就可以實現(xiàn)查詢方法Where:
???????#region?Where
????????///?<summary>
????????///?Where?從集合中選取符合條件的元素
????????///?</summary>???????
????????public?static?IList<TSource>?Where<TSource>(IEnumerable<TSource>?source,?Predicate<TSource>?predicate)
????????{www.elivn.com
????????????IList<TSource>?list?=?new?List<TSource>();
????????????GenericHepler.ForSpecification(source,?delegate(TSource?ele)?{?list.Add(ele);?}?,?predicate);
????????????return?list;
????????}?
????????#endregion ???對于C#3.0中的Select方法,其實現(xiàn)需要匿名類型的支持,而C#2.0中不支持匿名類型,所以,我用泛型來代替。我使用ConvertSpecification來模擬Select實現(xiàn):
???????#region?ConvertSpecification
????????///?<summary>
????????///?ConvertSpecification?將source中的符合predicate條件元素轉(zhuǎn)換為TResult類型
????????///?</summary>???????
????????public?static?IList<TResult>?ConvertSpecification<TSource,?TResult>(IEnumerable<TSource>?source,?Func<TSource,?TResult>?converter,?Predicate<TSource>?predicate)
????????{
????????????IList<TResult>?list?=?new?List<TResult>();
????????????GenericHepler.ForSpecification<TSource>(source,?delegate(TSource?ele)?{?list.Add(converter(ele));?}?,predicate);
????????????return?list;
????????}
????????#endregion ???converter委托用于從TSource類型對象構(gòu)造TResult類型的對象。
???有了ConvertSpecification實現(xiàn),我們就可以在其上繼續(xù)實現(xiàn)ConvertAll和ConvertFirstSpecification:
???????#region?ConvertAll
????????///?<summary>
????????///?ConvertAll?將source中的每個元素轉(zhuǎn)換為TResult類型
????????///?</summary>???????
????????public?static?IList<TResult>?ConvertAll<TSource,?TResult>(IEnumerable<TSource>?source,?Func<TSource,?TResult>?converter)
????????{
????????????return?GenericHepler.ConvertSpecification<TSource,?TResult>(source,?converter,?null);
????????}
????????#endregion
????????#region?ConvertFirstSpecification
????????///?<summary>
????????///?ConvertSpecification?將source中的符合predicate條件的第一個元素轉(zhuǎn)換為TResult類型
????????///?</summary>???????
????????public?static?TResult?ConvertFirstSpecification<TSource,?TResult>(IEnumerable<TSource>?source,?Func<TSource,?TResult>?converter,?Predicate<TSource>?predicate)
????????{
????????????TSource?target?=?GenericHepler.GetFirstSpecification<TSource>(source,?predicate);
????????????if?(target?==?null)
????????????{
????????????????return?default(TResult);
????????????}
????????????return?converter(target);
????????}
????????#endregion??????? ???有了上面的基礎(chǔ),我們還可以實現(xiàn)ContainsSpecification方法:
???????#region?ContainsSpecification
????????///?<summary>
????????///?ContainsSpecification?集合中是否包含滿足predicate條件的元素。
????????///?</summary>???????
????????public?static?bool?ContainsSpecification<TSource>(IEnumerable<TSource>?source,?Predicate<TSource>?predicate,?out?TSource?specification)
????????{
????????????specification?=?default(TSource);
????????????foreach?(TSource?element?in?source)
????????????{
????????????????if?(predicate(element))
????????????????{
????????????????????specification?=?element;
????????????????????return?true;
????????????????}
????????????}
????????????return?false;
????????}
????????#endregion????????
????????#region?ContainsSpecification
????????///?<summary>
????????///?ContainsSpecification?集合中是否包含滿足predicate條件的元素。
????????///?</summary>???????
????????public?static?bool?ContainsSpecification<TSource>(IEnumerable<TSource>?source,?Predicate<TSource>?predicate)
????????{
????????????TSource?specification;
????????????return?GenericHepler.ContainsSpecification<TSource>(source,?predicate,?out?specification);
????????}?
????????#endregion???????
???代碼中的注釋已經(jīng)將各個方法的用途說得非常清楚,下面我們舉兩個例子來看看如何使用它們以發(fā)揮它們的威力!
???例子一:比如,我們要從當前玩家(IPlayer)列表中找出所有年齡大于30歲的玩家的ID,通常這樣做:
????????{
????????????IList<string>?results?=?new?List<string>();
????????????foreach?(IPlayer?player?in?this.playerList)
????????????{
????????????????if?(player.Age?>?30)
????????????????{
????????????????????results.Add(player.ID);
????????????????}
????????????}
????????????return?results;
????????}
???如果使用上面我們封裝的API,則可以非常簡單地達到目的:
?public?IList<string>?GetOldPlayer()?{
?????return?GenericHepler.ConvertSpecification<IPlayer,?string>(this.playerList,?delegate(IPlayer?player)?{?return?player.ID;?}?,?delegate(IPlayer?player)?{return?player.Age?>?30?});????????????
?}
???一句搞定。
???
???例子二:我們要從當前的玩家字典(Dictionary)中取出所有ID不是指定集合中的ID的其它玩家列表。
???通常,我們可以這樣做:
????????{
????????????IList<IPlayer>?partnersList?=?new?List<IPlayer>();
????????????foreach?(string?userID?in?this.dicPlayers.Keys)
????????????{
????????????????bool?exclude?=?false;
????????????????foreach?(string?excludedUser?in?excludedUserIDs)
????????????????{
????????????????????if?(userID?==?excludedUser)
????????????????????{
????????????????????????exclude?=?true;
????????????????????????break;
????????????????????}
????????????????}
????????????????if?(!exclude)
????????????????{
????????????????????partnersList.Add(this.dicPlayers[userID]);
????????????????}
????????????}
????????????return?partnersList;?
????????}
???使用上面我們封裝的API,則非常簡單:
?public?IList<IPlayer>?GetPartners(params?string[]?excludedUserIDs)?{
?????return?GenericHepler.Where<IPlayer>(this.dicPlayers.Values,?delegate(IPlayer?player)?{?return?!GenericHepler.ContainsSpecification<string>(excludedUserIDs,?delegate(string?id)?{?return?id?==?player.UserID;?});?});????????????????????????????
?}
???靈活地使用這些API,我們可以非常簡潔地操作集合中的元素。
???最后給出GenericHepler類的源碼下載,其中還包含了幾個未介紹的實用的API。
轉(zhuǎn)載于:https://www.cnblogs.com/seoxs/archive/2011/04/20/2021838.html
總結(jié)
以上是生活随笔為你收集整理的【C#2.0】发挥匿名委托的威力!的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于 win7 远程桌面的多用户问题
- 下一篇: (转)CDN是如何工作的?