国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

.NetCollection的一些理解——記錄一次向?qū)嵙暽拇鹨?/h1>
2019-11-14 16:30:06
字體:
供稿:網(wǎng)友

公司最近進了個實習生,每天下班前我都會花一些時間來解答一下實習生的一些疑問。今天問起了關(guān)于集合排序方法Sort的一些疑問,這讓我一下回到自己剛剛?cè)胄械臅r候。那個時候也遇到了集合排序的問題,為發(fā)現(xiàn)接口IComparableICompare的妙處而興奮,還在公司的內(nèi)部分享會上分享了如何使用它們來排序。現(xiàn)在經(jīng)過多年的開發(fā)實踐以及學(xué)習,對于同一個問題又有了更加深入的理解。

一. 為什么說”實現(xiàn)了IEnumerable接口才能遍歷”

實習生先是問了這個問題, 其實這個問題, 非常容易解答.
先來看看IEnumerable接口的定義:

public interface IEnumerable{    IEnumerator GetEnumerator();}

這個接口非常簡單,主要就是一個方法GetEnumerator,用來返回一個IEnumerator對象。
繼續(xù)深入下去,IEnumerator接口的定義如下:

public interface IEnumerator{   bool MoveNext();      void Reset();     object Current {  get; }}

上面的IEnumerator接口定義的屬性和方法,只有一個目的,就是實現(xiàn)如何遍歷。下面具體解釋一下:

  • Current屬性, 用來返回當前集合項的值
  • MoveNext方法, 移動到集合對象的下一項,如果有下一項,就返回true, 如果沒有,就返回false.
  • Reset(), 重置然后可以重頭訪問集合

到這里,為什么foreach能夠遍歷集合對象的原因就是因為集合對象都實現(xiàn)了IEnumerable接口,提供了具體的實現(xiàn)來遍歷集合對象。

二. Sort()方法以及IComparable、IComparer接口

集合類型,都有Sort()排序方法,這個函數(shù)的一個重載版本中,需要提供一個IComparer類型的接口。為什么需要使用這個接口呢?這個和排序有什么關(guān)系?
想一想,實現(xiàn)排序必須的是什么?必須的是能夠比較大小。對于int, string這種.Net內(nèi)部類型,本身已經(jīng)支持了IComparer, 也就是可以比較大小了。但是對于我們自己定義的類型,使用Sort方法是無法排序的,因為程序不知道我們對于自定義對象的排序規(guī)則, 這個時候就可以使用IComparableIComparer.

下面舉一個實際的例子, 這里我們自定義了一個類Car, 然后對Car的集合進行排序.

public class Car{       public string Name { get; set; }       public int Year { get; set; }       public int Seats { get; set; }}

假如我們直接調(diào)用Sort方法, 就會悲劇拋出InvalidOperationException異常

image 

2.1 IComparable接口

IComparable 接口提供了比較某個特定類型對象的方法. 這里來說, 我們要讓Car實現(xiàn)IComparable 接口來達到比較Car對象的目的,從而實現(xiàn)排序。實現(xiàn)IComparable接口, 就必須實現(xiàn)CompareTo 方法, 具體如下:

public class Car: IComparable{       public string Name { get; set; }       public int Year { get; set; }       public int Seats { get; set; }       public int CompareTo(object obj)       {           var car = (Car) obj;           return String.CompareOrdinal(Name, car.Name);       }}

上面我們的Car對象實現(xiàn)了IComparable接口,按照Name字符串屬性來比較. 直接運行Sort()方法,就能夠得到排序結(jié)果:

image

2.2 IComparer接口

IComparer接口可以提供更加豐富和靈活的排序功能。 比如, 你可能需要在不同的場合,根據(jù)不同的屬性來排序.
下面就來實現(xiàn)一個根據(jù)Car的Year屬性來排序, 首先創(chuàng)建類CarYearComparer來對Car進行比較,比較是根據(jù)Year屬性

public class CarYearComparer: IComparer<Car>{       public int Compare(Car x,  Car y)       {           if (x.Year > y.Year)               return 1;           if (x.Year < y.Year)               return -1;           return 0;       }}

在調(diào)用Sort方法排序的時候,需要指定使用的IComparer實現(xiàn):

cars.Sort(new CarYearComparer());

得到的排序結(jié)果和上面的根據(jù)Name屬性不同:

image

還可以實現(xiàn)一個根據(jù)Car的屬性Seats排序的IComparer. 所以使用IComparer更加的靈活

3. 面向?qū)ο笤O(shè)計思想

Collection中的Sort()方法很好地遵循了開放封閉原則,既很好地完成了排序的功能,同時又開放出了入口,讓你可以為排序自定義規(guī)則。

下面是我個人的一些個人理解:
一個類應(yīng)該做自己擅長的事情和核心的事情(單一職責),把不擅長的交給別人。但是這個”別人“是不是任何人都可以呢?當然不是,為了更好的限定別人,我們使用了接口限定。
當一個類依賴于抽象(也就是接口),那么這個類的適用范圍就更加廣,就能夠更加超脫。老子一句”道可道,非常道;名可名,非常名”,正是沒有具體化,所以可以解釋萬物。

更多的面向?qū)ο笤O(shè)計原則,參照http://www.360doc.com/content/11/0521/00/3554006_118258005.shtml

最后附上本文相關(guān)源代碼: SortDemo


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表

主站蜘蛛池模板: 石城县| 馆陶县| 柳林县| 博乐市| 西乌| 铁岭县| 黔南| 裕民县| 武宣县| 静海县| 石家庄市| 北京市| 富川| 儋州市| 西盟| 鸡东县| 汶川县| 青田县| 故城县| 葵青区| 博乐市| 仲巴县| 沧源| 孟村| 威远县| 柳江县| 嘉义县| 建德市| 崇明县| 惠安县| 武川县| 文昌市| 辽阳县| 龙州县| 瓮安县| 松桃| 田东县| 甘肃省| 正宁县| 富宁县| 钦州市|