.NET框架是用于建立Inte.net時代應用程序的綜合性平臺,它允許開發人員建立使用Windows平臺的完全富于新特色的應用程序。在VS2008中,已經完全支持.net架構。在此筆者就以VS平臺為基礎, 談談對象的比較與復制等要點。
一、Equals()與==的差異性。
Equals與==都可以用來比較對象。他們的結果是否相同呢?可以這么說,他們兩個有本質的不同。作為程序開發人員必須深入的了解他們之間的差異,以便在后續編寫代碼的時候防止張冠李戴。
簡單的說,Equals測試兩個對象的等價性,而C#中的==用語測試引用是否相同。這是什么意思呢?假設筆者現在建立了如下兩個對象。
Dim sale1 as new person(“luobo”)
Dim sale2 as new person(“luobo”)
這兩條語句在VS平臺中建立了兩個對象,并且對其進行了初始化。這兩個對象雖然對象名字不同,但是都有相同的內容。此時如果分別用以上兩種方法會有什么不同的結果呢?當使用==符號來比較兩個對象的時候,其比較的是兩個對象的引用,或者更確切的說,比較的是兩個對象的物理存儲地址。很顯然這兩個對象雖然有相同的內容,但是其存儲的地址是不同的。為此最后得出的結果是False。相反,當使用equals方法比較兩個對象的時候, VS系統比較的是兩個對象的內容,而不是存儲其內容的地址。由于上面兩個對象具有相同的內容,為此得到的結果是true。
那么什么時候該用什么樣的方法呢?對于這個問題筆者做了一下總結。大家如果需要的話,可以參考如下的一些建議。
一是對于引用類型,可以使用==或者ls方法來測試引用的等價性。二是對于值類型,一般不能夠使用==或者ls方法來進行判斷。因為在定義中,值類型不能夠通過引用來訪問,故對他們進行比較在現實中是沒有實際意義的。三是值類型一般是使用派生出來的equals方法,測試內容是否相同,它們不能夠被覆蓋。筆者最強調一下,一般不能夠覆蓋用于引用類型的equlas方法。通常情況下可以對用戶類定義比較規則。如果不能夠覆蓋它,則默認的equals方法將會檢查引用的等價性。
另外需要注意的是在.net架構中還有一個比較有用的方法:referenceequals方法。其主要用來測試兩個引用是否指向同一個對象。如現在有兩個對象,很有可能起對應的是同一個地址。這就好象一個人有兩個名字一樣。對對象的內容更改時,這兩個引用所對應的內容也會隨之更改(因為他們實際上對應的是同一個對象)。如在刪除某個對象的時候,可能需要用到這個方法。
二、對象的淺拷貝與深拷貝。
在談到對象的比較時筆者提到過,有時候可能兩個引用指向同一個對象。如Sale1與Sale2都指向同一個對象Person。舉例來說,現在有一個文件。用戶在桌面上創建了這個文件的快捷方式。此時看起來有兩個文件,但是實際上這個兩個文件名字指向的都是同一個文件。要實現這個功能的話,就需要用到MemberwiseClone方法。簡單的說,這個方法就是用于產生對象的淺拷貝。
淺拷貝一般只著眼與對象的表層。如果某個對象包含到其他對象的引用,則這個引用就會被這個方法所拷貝。也就是說,不僅對象可以被拷貝,其對象的引用也是可以被復制的。不過在使用這個方法的時候,需要注意,其是受到保護的。通常情況下,只有派生出來的類才能夠調用這個方法。如開發人員通過如下方式來調用這個方法是不允許的。
Dim obj as new object1{}
Obj.memberwiseclone()
這主要是因為只有派生出來的類才能夠調用這個方法。另外需要注意的是,這種方法一般只適用引用的拷貝,而不適合對象的拷貝。有淺拷貝那么就有深拷貝。如果要單獨的拷貝一個對象,以及對象所引用的所有內容時(相當于是建立一個不同的對象,只是內容相同而已),就需要用到深拷貝。這主要是通過lconeable接口來實現的。采用深拷貝時,那么引用和指向的對象本身將都會被一起拷貝,或者說被拷貝的對象有了一個獨立的副本。
顯然深拷貝與淺拷貝都是涉及到對象的拷貝,但是實際的結果卻相差深遠。如果做一個形象的比較,淺拷貝就好象為某個文件建立一個“快捷方式”,而深拷貝就好象是“復制”了一個文件。表面上看起來一樣,其實兩者有本質的差異。作為開發人員,在應用程序設計與開發中,需要根據用戶的需求選擇合適的方法。如果需要的是兩個獨立的對象,那么就采用深拷貝。
三、等價的深入分析。
在VS平臺中管理對象時,了解等價的含義非常重要。因為在很多的地方都需要進行對象的比較。而不同類型的對象對于等價這個概念的理解都有所不同。也就是說,等價的具體含義還是主要決定于所考慮的對象的類型?;蛘哒f,不同的對象類型對于“等價”可能有不同的定義,不能夠一概而語。
如對于普通的值類型,等價的含義比較簡單,就只表示他們只要有相同的內容,就表示等價。在實際開發過程中,對此要有清晰的認識。特別是將這個結果作為IF條件語句的條件時,更加要慎重。否則的話,很容易導致相反的結果。
如現在要開發一個應用程序,其大致的功能是:如需要在數據庫中尋找條件符合年齡等于25歲、性別為男、戶籍為浙江寧波的人的信息。此時可以建立一個對象,就涉及到對象的比較。根據這個需求,可以知道其主要比較的是內容。只要對象的內容相同即可。而不用管對象的地址。也就是說,這個需求中等價的含義是針對內容。如果不對此進行精確的定義,那么最后判斷的結果就會相差很多。
筆者最后強調一次,等價的含義取決于所考慮的對象的類型。對象的類型不同,其等價的具體內涵是不同的。故當涉及到不同類型的對象比較時,該采取合適的方法?;蛘哒f,在比較對象之前,需要先對對象的類型進行強制的轉換。
原文轉自:http://www.anti-gravitydesign.com