5.3.3 新增型別還是函式
正如我們早先提到過的,在 f# 和 c# 中,函式 schedule 資料型別在乙個方向不可擴充套件:很難新增乙個新的事件的型別。在 f# 中,出現困難的原因是,需要修改型別宣告;如果它在乙個共享庫中,必須重新編譯這個共享庫。同樣,在 c# 版本中,我們有乙個 tag 屬性,這使得新增新型別更困難。另一方面,這種設計的好處是,使我們能夠很容易為了處理計畫,而新增新的功能。
讓我們研究一下函式和物件導向解決方案之間的差異。圖 5.2 顯示兩個類層次結構表示兩種可能的方法。在物件導向的版本中,所有的功能都被括在虛擬方法。函式版本公開的 tag 屬性可用於標識值表示的那個選項。
圖 5.2 表示計畫,使用通常的物件導向設計(左圖),使用帶 tag 屬性的函式方法(右圖)
下面列出了函式程式設計風格(fp)與通常的物件導向風格的之間的主要區別,我們看到在**示例中所看到的。
■ fp 版本使新增處理資料型別的新功能容易,通過編寫使用模式匹配的乙個函式就能實現。但是,新增新型別的表示困難。
■ 物件導向的版本使新增新型別的表示很容易,通過編寫新的繼承類並實施其虛擬的方法實現。但是,新增新的虛擬方法困難。
■ 在 fp 版本中,單一功能的**都在乙個地方,所以,與一種計算有關的所有**是在單獨的函式中。
■ 在物件導向版本中,單個型別的**都 在乙個地方,這意味著,使用特定表示的所有**都在乙個類宣告中。
如你所見,關鍵問題是我們是要使哪乙個更容易,是新增新型別,還是新函式。經驗表明,在函式程式設計中,更常見的是,要向現有型別新增新的功能。
如果你熟悉通常的設計模式,可能還記得訪問者模式,這是物件導向的處理資料結構的方式,就像差別聯合。我們將第 7 章討論遞迴的差別聯合時再說,因為,它通常用於處理複雜的程式資料,而不是簡單的值。也要等到第 7 章,才會討論是否選擇差別聯合,因為這個問題更多的與程式資料有關,但是,你可以先看看側邊欄「在現實世界中的差別聯合」,有幾個使用差別聯合的例子。
在現實世界中的差別聯合
使用差別聯合更優雅實現類層次結構的乙個例子是,可以的.net 3.5 的 linq 專案引入的表示式(expression)型別,它用來儲存表示式樹,這是表示資料結構,解析表示式的源**(例如,1 + x)。這個型別具有繼承類,對於每個可能的表示式型別,如 binaryexpression,可以表示加和(或)其他二元運算,例如,constantexpression,這用於儲存文字。這個型別也有乙個屬性類似於 tag 屬性,但它使用的名字是 nodetype。一般而言,每當你處理某種形式的源**,或由使用者輸入的簡單表示式,差別聯合可能是正確的選擇。
差別聯合很有用的另乙個例子是,表示如二叉樹的資料結構。樹可以攜帶一些值的葉子,或者是內部的樹節點,由兩個二叉樹組成。樹是函式程式設計中經常使用的資料結構,所以,會在第 8、 10、 15 章中看到。
在本章中,我們討論了簡單值:任何簡單的表示為有限的可選值集合的通用值,應該始終選擇差別聯合。這是因為,對於這種值,幾乎可以肯定的是想要新增新的功能,而不是新增新的型別。有乙個差別聯合,在函式程式設計中非常有用的,存在於所有的函式語言:f# 中它被稱為選項(option)型別。
5 3 3 新增型別還是函式
5.3.3 新增型別還是函式 正如我們早先提到過的,在 f 和 c 中,函式式資料型別 schedule 在乙個方向不可擴充套件 很難為事件新增新的型別。在 f 中,困難的原因在於需要修改型別宣告,如果型別在共享庫中,必須重新編譯這個共享庫 同樣,在 c 版本中,tag 屬性使得新增新型別更困難。另...
string 值型別還是引用型別
大家先來看一下下面的 吧!1using system 2using system.collections.generic 34 public class myclass5,a,s 12 1314 輸出的是abc,def 我們都知道陣列是引用型別的,請看一下段 1using system 2class...
關於string是值型別還是引用型別
當然了,string本質上肯定是引用型別,但是這個特殊的類卻表現出值型別的特點 判斷相等性時,是按照內容來判斷的,而不是位址 它肯定是乙個引用型別沒錯,兩個方面來看 1.class string繼承自object,而不是system.valuetype int32這樣的則是繼承於system.val...