當方法返回型別或屬性型別為集合時,有些開發者會千篇一律地使用ilist集合。然而ilist具有集合的所有操作,這意味著呼叫者不僅可以讀取集合資訊,還能夠修改集合。業務需求本來只是為呼叫者提供乙個可讀的集合,例如資料的查詢和展示,但當方法返回ilist時,無疑隱式地開放了集合可寫的許可權。此時,我們無法阻止呼叫者篡改集合元素。
注意:將屬性設定為ilist型別時,即使宣告為唯讀的,我們仍然無法避免集合元素的篡改。
例如public ilistpeople
,people屬性是乙個ilist集合,它雖然是唯讀的,但是people集合裡面的元素可以被修改。
這種情況下,我們應該使用ienumerable來代替ilist。
ilist和ienumerable都可以遍歷集合的元素,ilist擁有集合的所有操作方法,包括集合元素的增加、修改和刪除。
而ienumerable則只有乙個getenumerator方法(擴充套件方法除外),它返回乙個可用於迴圈訪問集合的ienumerator物件。
下面這段**定義了兩個類:order和orderline。
當呼叫者在取到order例項時,仍然可以通過ilist的add()或remove()方法修改orderlines集合。
假設呼叫者篡改了orderlines中的元素,並且通過另外的方法回傳了order例項,則可能會產生一些bug。
隱藏**
/// /// 訂單重構後,不僅orderlines集合是唯讀的,而且也只能通過addorderline()和removeorderline()方法來增加或刪除訂單明細。///
public class order
}public void addorderline(orderline orderline)
public void removeorderline(orderline orderline)
}/// /// 訂單明細
///
public class orderline
}
隱藏**
/// /// 訂單注意:上述**有一些瑕疵,orderline類沒有重寫object類的equals()、gethashcode()方法。///
public class order
/// /// 訂單明細集合是唯讀的,只能通過addorderline()和removeorderline()來增加或刪除訂單明細
///
public ienumerableorderlines
}public double ordertotal
}public void addorderline(orderline orderline)
public void removeorderline(orderline orderline)
}/// /// 訂單明細
///
public class orderline
}
這行**orderline = _orderlines.find(item => item == orderline)會使得orderline每次都是null。
較為完整的orderline如下:
隱藏**
public class orderline當集合作為返回引數時,應使用適合業務需求的集合型別,不宜提供過多的集合操作給呼叫者。public int orderid
public double total
/// /// 重寫equals方法
///
public override bool equals(object obj)
return id.equals(other.id);
}/// /// 重寫gethashcode方法
///
///
public override int gethashcode()
/// /// 是否為瞬時物件
///
///
public virtual bool istransient()
/// /// 提供==操作符,可用於物件比較
///
public static bool operator ==(orderline left, orderline right)
return left.equals(right);
}/// /// 提供!=操作用,可用於物件比較
///
public static bool operator !=(orderline left, orderline right)
}
小酌重構系列目錄彙總
關注keepfool
3 11 封裝集合
封裝集合 範例 1 include 2 define max student count 2034 class student512 13int getid const 1417 void setid int nid 1821 qstring getname const 2225 void setn...
31 天重構學習筆記1 封裝集合
摘要 由於最近在做重構的專案,所以對重構又重新進行了一遍學習和整理,對31天重構最早接觸是在2009年10月份,由於當時沒有訂閱 sean chambers的blog,所以是在國外的社群上閒逛的時候鏈結過去的。記得當時一口氣看完了整個系列並沒有多少感覺,因為這些基本上專案都 在使用,只是我們沒有專門...
物件導向系列二(封裝)
僅僅須要最簡單的操作就能實現一系列複雜的功能。是做乙個個技術攻克的目的。一台精密儀器,一架家用電器,乙個小公尺手機,這些可能我們都在用,或者用過。它們的內部都無比的複雜。使用了各種各樣的配件,運用了極多的原理和知識。我們在使用的時候都具有同樣的感受 簡單 方便 太好了!面對原本複雜的東西,我們卻能通...