今天面試的時候被問到C#中的引用,因為在這之前討論的是C++的指針和引用,所以當時下意識的以為面試官想考察C#中修改傳遞參數(shù)的問題,就往ref和out方向上談了談。后來想想,好像我對C#的引用類型的印象也就只有string和object了,回來思考了下,結(jié)合以前所學,對C#中的引用相關(guān)知識進行了一下梳理。
C#的引用類型不同于值類型,在??臻g上存儲引用,在堆空間上存儲值。C#的引用類型主要包括內(nèi)建引用、class和interface。C# 中方法參數(shù)傳遞有四種方式,值傳遞、引用傳遞、輸出參數(shù)和數(shù)組參數(shù)。若要通過引用傳遞參數(shù), 可使用ref或out關(guān)鍵字。
C#的內(nèi)置引用類型包括object,string和dynamic三種。前兩者對于變量的類型檢查是在編譯階段,而dynamic強制了對變量的類型檢查是在運行階段。object是C#中所有類型的基類。一般的引用類型有ToString和GetType兩種方法,不同類型的ToString方法返回的結(jié)果不同,object類型只是簡單地返回了類型名稱System.Object,其他類型的ToString可能返回實際的值。object類型的判斷相等運算符是判斷內(nèi)存存儲地址是否相同。而string類型的判斷相等運算符則被重載為判斷值相等。string類型的其他操作還包括連接、獲得某位字符。string類型在聲明以及初始化之后長度就固定了,如果需要增刪字符串的字符,則需要重新分配字符串的內(nèi)存空間。頻繁對string執(zhí)行這樣的操作,會使系統(tǒng)產(chǎn)生很大的開銷負擔。若需要頻繁的增刪字符,建議使用StringBuilder。dynamic的話感覺不是很常用,似乎是將所有類型都當作object來處理。
C#中最基本最常用的引用類型就是class。class的默認修飾符是internal,在namespace空間內(nèi)都可以訪問。而Class的字段和方法的默認修飾符是private,只有在class內(nèi)部才可以訪問到。相比起成員方法,C#更常通過屬性來訪問內(nèi)部字段,因為這樣可以做訪問控制,滿足安全性和封裝性,而且寫起來比方法簡煉。
C#中另一種基本的引用類型是interface,interface一般被拿來和abstract class進行比較。抽象類本質(zhì)上仍然是類,它不能被實例化,但可以包含字段、非抽象方法和抽象方法。其他類繼承抽象類,需要實現(xiàn)抽象方法,對于非抽象方法,可以選擇繼承或重載。interface更像是一個規(guī)則,只能包含屬性、方法、索引和事件,不能包含字段,一個類繼承接口需要實現(xiàn)所有接口方法。一個類只能繼承一個抽象類,卻可以實現(xiàn)多個接口。
C#中,顯示傳遞ref或out關(guān)鍵字的方法參數(shù)都被認為是進行引用傳遞。共同點是在方法中對參數(shù)的更改都將反應(yīng)在該變量中。一個方法允許包含多個ref或out型參數(shù)。屬性不是變量,不能通過ref或out來進行傳遞。另外在方法聲明和執(zhí)行時都要顯示注明ref和out,否則編譯不通過。不同點在于ref型參數(shù)要求傳入?yún)?shù)已經(jīng)初始化,out型參數(shù)要求參數(shù)在返回之前被初始化。可變參數(shù)params后面必須跟數(shù)組,之后不允許任何其他參數(shù),并且在方法聲明中只允許一個 params 關(guān)鍵字。