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

歡迎訪問 生活随笔!

生活随笔

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

C#

c# 扩展方法奇思妙用基础篇八:Distinct 扩展(转载)

發布時間:2024/4/17 C# 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c# 扩展方法奇思妙用基础篇八:Distinct 扩展(转载) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉載地址:http://www.cnblogs.com/ldp615/archive/2011/08/01/distinct-entension.html

剛看了篇文章 《Linq的Distinct太不給力了》,文中給出了一個解決辦法,略顯復雜。

試想如果能寫成下面的樣子,是不是更簡單優雅:

1 2 var p1 = products.Distinct(p => p.ID); var p2 = products.Distinct(p => p.Name);

使用一個簡單的 lambda 作為參數,也符合 Linq 一貫的風格。

可通過擴展方法實現:

Distinct 擴展方法

首先,創建一個通用比較的類,實現 IEqualityComparer<T> 接口:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 using System; using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Linq;public class CommonEqualityComparer<T, V> : IEqualityComparer<T> {private Func<T, V> keySelector;public CommonEqualityComparer(Func<T, V> keySelector){this.keySelector = keySelector;}public bool Equals(T x, T y){return EqualityComparer<V>.Default.Equals(keySelector(x), keySelector(y));}public int GetHashCode(T obj){return EqualityComparer<V>.Default.GetHashCode(keySelector(obj));} }

第 17 行,用到了?EqualityComparer<T> 類,本文最后有簡要說明。

借助上面這個類,Distinct?擴展方法就很好寫了:

1 2 3 4 5 6 7 public static class DistinctExtensions {public static IEnumerable<T> Distinct<T, V>(this IEnumerable<T> source, Func<T, V> keySelector){return source.Distinct(new CommonEqualityComparer<T, V>(keySelector));} }

呵呵,簡單吧!

Distinct 使用示例

根據 ID :

1 2 3 4 5 6 7 var data1 = new Person[] {new Person{ ID = 1, Name = "鶴沖天"},new Person{ ID = 1, Name = "ldp"} }; var ps1 = data1.Distinct(p => p.ID).ToArray();

根據 Name:

1 2 3 4 5 7 var data2 = new Person[] {new Person{ ID = 1, Name = "鶴沖天"},new Person{ ID = 2, Name = "鶴沖天"} }; var ps2 = data2.Distinct(p => p.Name).ToArray();

看了回復后,我做了些改進,推薦使用下面的方式

改進

回復中有朋友提到“不區分大小寫地排除重復的字符串”,也不難實現,只需要把上面的代碼改進下就 OK:

CommonEqualityComparer<T, V> 類:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 using System; using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Linq;public class CommonEqualityComparer<T, V> : IEqualityComparer<T> {private Func<T, V> keySelector;private IEqualityComparer<V> comparer;public CommonEqualityComparer(Func<T, V> keySelector, IEqualityComparer<V> comparer){this.keySelector = keySelector;this.comparer = comparer;}public CommonEqualityComparer(Func<T, V> keySelector): this(keySelector, EqualityComparer<V>.Default){ }public bool Equals(T x, T y){return comparer.Equals(keySelector(x), keySelector(y));}public int GetHashCode(T obj){return comparer.GetHashCode(keySelector(obj));} }

Distinct?擴展方法:

1 2 3 4 5 6 7 8 9 10 11 12 public static class DistinctExtensions {public static IEnumerable<T> Distinct<T, V>(this IEnumerable<T> source, Func<T, V> keySelector){return source.Distinct(new CommonEqualityComparer<T, V>(keySelector));}public static IEnumerable<T> Distinct<T, V>(this IEnumerable<T> source, Func<T, V> keySelector, IEqualityComparer<V> comparer){return source.Distinct(new CommonEqualityComparer<T, V>(keySelector, comparer));} }

借助可選參數,這兩個擴展方法也可以合成一個:

1 2 3 4 5 public static IEnumerable<T> Distinct<T, V>(this IEnumerable<T> source, Func<T, V> keySelector, IEqualityComparer<V> comparer = EqualityComparer<V>.Default) {return source.Distinct(new CommonEqualityComparer<T, V>(keySelector, comparer)); }

(同樣,CommonEqualityComparer<T, V>類的兩個構造函數也可以合二為一)

使用示例:

1 2 3 4 5 6 7 var data3 = new Person[] {new Person{ ID = 1, Name = "LDP"},new Person{ ID = 2, Name = "ldp"} }; var ps3 = data3.Distinct(p => p.Name, StringComparer.CurrentCultureIgnoreCase).ToArray();

EqualityComparer<T> 類 簡要說明

EqualityComparer<T>為?IEqualityComparer<T>?泛型接口的實現提供基類,它在 .net 4 中有五個重要的子類,見下圖:

這五個子類分別用不同類型數據的相等性比較,從類名我們可以略知一二。

這五個子類都是內部類(internal),不能直接訪問,EqualityComparer<T> 類提供一個簡單的屬性 Default。EqualityComparer<T> 會根據傳入的 T 的類型,加載不同的子類,并會予以緩存提高性能。



c#擴展方法奇思妙用》系統文章從 2009 年 08 月開始寫起,到現在一共有了 22 篇,歡迎閱讀:
基礎篇:中文處理、string 常用擴展、byte 常用擴展、Random 擴展、Dictionary<TKey, TValue> 擴展、WhereIf 擴展、IsBetween 通用擴展、WhereIf 擴展、Distinct 擴展
高級篇:改進 Scottgu 的 "In" 擴展、Aggregate擴展其改進、Enumerable.Cast<T>應用、對擴展進行分組管理、ToString(string format) 擴展、WinForm 控件選擇器、樹”通用遍歷器、Type類擴展
變態篇:由Fibonacci數列引出“委托擴展”及“遞推遞歸委托”、封裝 if/else、swith/case及while、switch/case 組擴展、string 的翻身革命
性能篇擴展方法性能初測
MVC篇:巧用擴展方法優先級,美化所有頁面TextBoxFor文本框

-------------------

轉載于:https://www.cnblogs.com/yxlblogs/p/3737164.html

總結

以上是生活随笔為你收集整理的c# 扩展方法奇思妙用基础篇八:Distinct 扩展(转载)的全部內容,希望文章能夠幫你解決所遇到的問題。

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