類型的劃分 一個類型,要麼是值類型,要麼是引用類型 。區別在於拷貝方式:值類型拷貝值,引用類型拷貝引用 值類型 值類型直接包含值。相當於每一個值類型都有自己單獨的值: int a = 10; int b = a; a和b都有著自己的值,修改a並不會影響b,反過來一樣,互不影響。 即使是將實例傳給Co ...
類型的劃分
一個類型,要麼是值類型,要麼是引用類型。區別在於拷貝方式:值類型拷貝值,引用類型拷貝引用
值類型
值類型直接包含值。相當於每一個值類型都有自己單獨的值:
int a = 10;
int b = a;
a和b都有著自己的值,修改a並不會影響b,反過來一樣,互不影響。
即使是將實例傳給Console.WriteLine()這樣的方法也會產生記憶體拷貝。由於值記憶體需要創建記憶體拷貝,因此定義的時候不要讓它們占用太多記憶體。
引用類型
引用類型的變數存儲對數據存儲位置的引用,而不是直接存儲數據。也就是說,要到對應的位置才能找到真正的數據。因此為了訪問數據,“運行時”要先從變數中讀取記憶體位置,再“跳轉”到包含數據的記憶體位置。引用類型指向的記憶體區為成為堆。
正如前面所說,引用類型拷貝引用,它不包含值,每次引用變數的賦值都是引用的拷貝,並不需要拷貝數據。
值得註意的一點,引用類型只複製對數據的引用,所以兩個不同的變數可引用相同的數據。在這種情況下,只要數據發生了改變,就會影響到所引用到他的變數的值,畢竟都是引用同一個數據。
可空修飾符
我之前提到過null值,它是給引用變數表示為空的值,一般不能將它賦值給值類型。根據定義,值類型不能包含引用。但是有的時候我們的確又有這一方面的需求,所以為了聲明能存儲null變數,要使用可空修飾符"?"。示例:
int? cnt = null;
隱式類型的局部變數
關鍵字:var,用於聲明隱式類型的局部變數。示例:
var text = Console.WriteLine();
這麼做最終的CIL代碼並沒有區別,但var告訴編譯器根據聲明時所賦的值來推斷數據類型。
雖然允許用var取代像是數據類型,但是在已知數據類型的情況下還是不要這麼做,明確的聲明數據類型不僅能夠增加可讀性,還相當於親自確認了等號右邊返回的是你所需要的數據類型。
匿名類型能夠在方法內部動態聲明數據類型,並不需要通過顯式的類定義來聲明,示例:
var people1 = new { Name = "Van", Say = "啊?" };
var people2 = new { Name = "Bili", Say = "乖乖站好" };
System.Console.WriteLine( $"{people1.Name} {people1.Say}");
System.Console.WriteLine( $"{people2.Name} {people2.Say}");
元組
有時候需要合併數據元素。元組正好可以解決這個問題,它允許在一個語句內完成所有變數的賦值。
以下是它的語法形式:
將元組賦給單獨聲明的變數:
(string power, string name, int weight) = ("超高校的幸運", "脖子直抖", 65);
將元組賦給預聲明的變數:
string power, name;
int weight;
(power, name, weight) = ("超高校的幸運", "脖子直抖", 65);
將元組賦給隱式類型的變數:
var (power,name,weight) = ("超高校的幸運", "脖子直抖", 65);
註意:此處以及下麵包含的 var 絕不能如果替換成顯示類型(如string或int)。因為元組宗旨是允許每一項都有不同的數據類型,所以每一項都指定同一個顯示類型名稱和這個宗旨衝突,即便是真的一樣,編譯器也不允許指定顯示類型。
聲明具名元組,將元組值賦給它。
(string power, string name, int weight) people = ("超高校的幸運", "脖子直抖", 65);
聲明包含具名元組項的元組,將其賦給隱式類型的變數。
var people = (power:"超高校的幸運", name:"脖子直抖", weight:65);
將元組項未具名的元組賦給隱式類型的變數,再通過向編號屬性訪問單獨的元素。
var people = ("超高校的幸運", "脖子直抖", 65);
people.Item1;//people.Item2;
若是具名元組還是可以通過項目編號屬性訪問單獨的元素。
賦值時用下劃線丟棄元組的一部分數據(棄元)。
(string power, _, int weigth) people = ("超高校的幸運", "脖子直抖", 65);
數組
數組能夠在單個變數中存儲同一種類型的多個數據項,並且可以通過索引來單獨訪問這些數據項。數組的數據線索引從0開始,最大索引值總是比數組中的數據項少1。但是現在大多數程式都使用泛型集合類型而非數組來存儲數據集合。
數組聲明
數組聲明,直接上代碼:
string[] arr1;
方括弧在數據類型之後,變數名之前。
聲明二維數組的方法,代碼:
string[,] arr2;
在用逗號進行多維數組的聲明,總共維數等於逗號加一。
數組的實例化和賦值
數組可在聲明的同時初始化,例如:
string[] arr3 = {"1","1","4","5","1","4"};
元素的下標對應就是對應元素的位置,依次排列。
也可以先聲明數組再進行賦值,如下:
string[] arr4;
arr4 = new string[]{"1","1","4","5","1","4"};
但是從C#3.0開始就不必在new之後指定數組類型。編譯器能根據初始化列表中的數據類型推斷數組類型。如下:
arr4 = new []{"1","1","4","5","1","4"};
上面使用了new關鍵字,它指示“運行時”為資料庫類型分配記憶體,也就是實例化數據類型。
我們也可以給數組分配固定大小但不提供初始化,也可以指定大小並賦值,如下:
string[] arr5 = new string[6]{"1","1","4","5","1","4"};
數組在沒有被初始化的時候,“運行時”會給每個元素初始化為他們的預設值:
- 引用類型會被初始化為null。
- 數字類型會被初始化為0。
- bool初始化為false。
- char類型初始化為\0。
多位數組註意不要超出對應的聲明範圍,這裡不再討論。
數組的使用
可以用方括弧表示法(數組訪問符)來訪問數組中一個特定的數據項。註意下標是從0開始的,最大下標是數組內容減一。
arr1[1];//表示arr1數組中第二個元素的內容
二維數組同理。
交錯數組,也就是數組數組,用數組來存儲數組,聲明方式如下:
int[][] arr6 = {
new int[]{1,1,1};
new int[]{2,2,2};
new int[]{3,3,3};
}
當然數組也有一些方法,下麵進行舉例:
- arr.Length:獲取數組的長度,只讀。
我們在訪問數組的邊界元素時,一般會採取Length-1這樣的方式來訪問數組邊界成員。
- System.Array.Sort():對數組內容進行排序。
- System.Array.BinarySearch(var[] arr, var searchString):返回搜索值的索引,不存在就返回-1。前提是按升序排序。
- System.Array.Clear(intArray, 0, intArray.Length):清空第0到第intArray.Length個索引的元素(置零)。
- System.Array.Reverse(arr):反轉數組順序。
還有眾多方法,這裡不一一列舉,看個樂呵。
字元串作為數組使用
我們需要註意的是,字元串是不可變的,字元串作為數組使用時,我們訪問到的成員變數都是char類型的變數。為此將字元串作為數組使用時要註意不能去修改成員變數的內容。
小結
本次博文的內容介紹了更多的數據結構,但是這也只是開始,介紹了值類型,引用類型,隱式類型,元組以及數組,這些內容都會貫徹到我們今後的項目之中,一定要打好堅實的基礎,當然不是說要背下來,理解到位才是我們應該去做的。