前言
工作之中,我們習慣了碰到任務就直接去實現其業務邏輯,但是C#真正的一些基礎知識,在我們久而久之不去了解鞏固的情況下,就會忽視掉。我深知自己正一步步走向只知用法卻不知原理的深淵,所以工作之余,一直想找一些能深入講解C#基礎知識和底層原理的書籍,有幸在網上看到了《.net之美》一書,(--張子陽作 )開始只是簡單的做了閱讀,但是越往下讀,發現書中所述都是自己所薄弱或者是工作中遇到但是解釋不清其原理的知識點,為了加深自己的印象,故萌生出寫下讀書筆記的想法,也是為自己的學習有個記錄,方便日后查閱,加深理解。
一. C#語言基礎
1.1 C# 類型基礎
C#的類型共分為兩種: 值類型和引用類型. 當然,區分他們的不同是以其在計算機內存中的分配方式不同
來划分的
1.值類型總是分配到它聲明的地方:
a.作為引用類型的成員變量分配到“堆”上
b.作為方法的局部變量時分配到“棧”上
2.引用類型總是被分配到"堆"上
3.當聲明一個值類型的變量時,變量本身包含了值類型的全部字段,該變量將被分配在線程堆棧上。
4.當聲明一個引用類型變量,並使用new操作符創建引用類型實例的時候,該引用類型的變量會被分配到線程棧上,變量保存了位於堆上引用類型的實例的內存地址。變量本身不包含任何類型所定義的數據。
public class RefPoint
{
public int x;
public RefPoint(int x){
this.x=x;
}
public RefPoint(){};
}
當僅聲明不實例化時,RefPoint r1; 只在線程棧上創建一個不包含任何數據,也不指向任何對象 (不包含內存地址)的變量
當使用new操作符實例化該變量時,r1=new RefPoint(1);將完成以下幾件事
- 在應用程序堆上創建一個引用類對象的實例,並為其分配內存地址
- 自動傳遞該實例的引用給構造函數。
- 調用該類型的構造函數 public RefPoint(int x){}
- 返回該實例的引用,賦值給r1變量。
5.裝箱和拆箱
裝箱就是將一個值類型轉換成等價的引用類型,拆箱則是將一個已裝箱的引用類型轉換為值類型。
注:拆箱操作需要顯示聲明拆箱后轉換的類型。因為拆箱裝箱需要反復在內存堆上進行,因此,在我們實際的程序應用中,應該避免沒有意義的裝箱和拆箱操作,以此來減少我們的內存消耗。
6.引用類型判等
System.Object基類中,定義了實例方法Equals(object obj)、靜態方法Equals(object objA,object objB)、靜態方法 ReferenceEquals(Object objA,Object objB) 三種方法來判斷兩個引用類型是否相等。
作者給出了以上三種方法的具體實現,如下所示:
public static bool ReferenceEquals (Object objA, Object objB)
{
return objA == objB; // #1
}
public virtual bool Equals(Object obj)
{
return InternalEquals(this, obj); // #2
}
public static bool Equals(Object objA, Object objB) {
if (objA==objB) { // #3
return true;
}
if (objA==null || objB==null) {
return false;
}
return objA.Equals(objB); // #4
}
ReferenceEquals(),判斷的是兩個引用變量是不是指向了同一個變量,如果是,則返回true,這種相等就是引用相等。等同於==。
另外需要注意的就是 對於引用類型,即使類型的實例包含的值相等,但是如果變量指向的是不同的對象,即引用值針的地址不相等,那么這兩個變量也是不相等的。
7.簡單值類型判等
簡單值類型:值類型的成員僅包含值類型;
復雜值類型:值類型的成員包含引用類型;
值類型的判等,會調用System.ValueType的Equals()方法。方法內容簡單的來講就是 先判斷兩個對象是不是同一個類型,如果不是,直接返回false,接着來判斷對象內所有的字段,利用反射機制取到值類型的所有字段,遍歷字段,進行字段與字段的比較。
8.對象復制
淺度復制:對於值類型成員,會復制其本身;對於引用類型成員,僅僅復制引用,而不在堆上重新創建對象。結果就是 新對象的引用成員和復制對象的引用成員指向了同一個對象。
相對的,深度復制:就是將引用成員指向的對象也進行復制。過程就是創建新的引用成員指向的對象,然后復制對象中所包含的數據。
9.常量性和原子性
對象的原子性:對象的狀態是一個整體,如果一個字段改變,其他字段也要同時做出相應改變。
如何實施?? 添加一個構造函數,在構造函數中為對象的所有字段賦值。
對象的常量性:對象的狀態一旦確定,就不能再次更改了。如果想再次更改,需要重新創建新的對象。
如何實施??可將屬性中的set訪問器刪除,同時將字段聲明為readonly只讀狀態。
二.小結
作者在這一章節主要講解了C#中的類型,包括值類型和引用類型,以及簡單類型和拆箱裝修的過程,以及后續的對象判等、深淺復制及對象的一些特性等。通過對此章節的閱讀,加深並鞏固了我對於C#這些基礎概念的理解,大學肯定也學過這些,但是隨着步入工作后,慢慢接觸到的都是工作中的業務邏輯處理了,關心的也是業務邏輯該如何實現等,很少再有精力去回過頭了解基礎的一些知識點。
今天上午還在網上看到某個大佬發布的一篇博文,大概意思就是30+的程序員面試的一些過程,看完感覺感觸很深,雖然我今年27,離30+也不遠了,但是工作中,總感覺自己一旦閑下來就很慌,是那種不知所措的心里慌,很想去看點關於基礎知識點的書籍,但是一看到知識點概念就看不進去了,偶爾還有其他事情要忙,只能草草收場,等到下次再想起來的時候,已經記不清上次自己看到哪里了,所以寫下這篇文章也是為了防止自己再放棄,算是給自己一個鼓勵吧。
曾經問過一位博主大佬,為什么文章寫的那么好,感覺什么都能拿來作文章的素材,再看看自己,雖然也在努力,但是沒有目標,沒有方向。2020年也快過完了,去年定下的目標也忘的差不多了,就希望接下來的時間里,能抓緊時間,充實自己吧。