Employee e1 = Employees.Find( "CEO" );
e1.Salary += Bonus; // Add one time bonus.
e1.Pay( CEOBankAccount );
就是這個一次性的在工資中添加 紅利的操作,成了持續的提升。曾經是值類型COPY的地方,如今都變成了引用類 型的引用。編譯器很樂意為你做這樣的改變,你的CEO更是樂意這樣的改變。另 一方面,你的CEO將會給你報告BUG。
你還是沒能改變對值類型和引用類 型的看法,以至於你犯下這樣的錯誤還不知道:它改變了行為!
出現這個 問題的原因就是因為Employee已經不再遵守值類型數據的的原則。
另外 ,定義為Empolyee的保存數據的元素,在這個例子裡你必須為它添加一個職責: 為雇員付工資。職責是屬於類范圍內的事。類可以被定義多態的,從而很容易的 實現一些常見的職責;而結構則不充許,它應該僅限於保存數據。
在值 類型和引用類型間做選擇時,.Net的說明文檔建議你把類型的大小做為一個決定 因素來考慮。而實際上,更多的因素是類型的使用。簡單的結構或單純的數據載 體是值類型數據優秀的候選對象。事實表明,值類型數據在內存管理上有很好的 性能:它們很少會有堆內存碎片,很少會有垃圾產生,並且很少間接訪問。
(譯注:這裡的垃圾,以及前面提到過的垃圾,是指堆內存上“死 ”掉的對象,用戶無法訪問,只等著由垃圾回收器來收集的對象,因此認 為是垃圾。在.net裡,一般說垃圾時,都是指這些對象。建議看一下.Net下垃圾 回收器的管理模型)
更重要是:當從一個方法或者屬性上返回時,值類型 是COPY的數據。這不會有因為暴露內部結構而存在的危險。But you pay in terms of features. 值類型在面向對象技術上的支持是有限的。你應該把所有 的值類型當成是封閉的。你可以建立一個實現了接口的值類型,但這須要裝箱, 原則17會給你解釋這會帶來性能方面的損失。把值類型就當成是一個數據的容器 吧,不再感覺是OO裡的對象。
你創建的引用類型可能比值類型要多。如 果你對下面所有問題回答YES,你應該創建值類型數據。把下面的問題與前面的 Employee例子做對比:
1、類型的最基本的職責是存儲數據嗎?
2 、它的屬性上有定義完整的公共接口來訪問或者修改數據成員嗎?
3、我 對類型決不會有子類自信嗎?
4、我對類型決不會有多太性自信嗎?
把值類型當成一個低層次的數據存儲類型,把應用程序的行為用引用類 型來表現。
你會在從類暴露的方法那取得安全數據的COPY。你會從使用 內聯的值類型那裡得到內存使用高率的好處。並且你可以用標准的面向對象技術 創建應用程序邏輯。當你對期望的使用拿不准時,使用引用類型。
=================================
小結:這一原則有點長, 花的時間也比較多一點,本想下班後,兩三個小時就搞定的,因為我昨天已經翻 譯了一些的,結果,還是一不小心搞到了11點。
最後說明一個,這一原 則還是沒有說明白什麼是引用類型什麼是值類型。當然,用class說明的類型一 定是引用類型,用struct說明的是值類型。還要注意其它一些類型的性質:例如 :枚舉是什麼類型?委托是什麼類型?事件呢?
返回教程目錄