C#支援兩種類型:實值型別和參考型別。實值型別包括簡單類型(如char,int,和float),枚舉類型,以及結構類型。參考型別有類、介面、委託和數群組類型。
實值型別和參考型別的區別在於:實值型別變數直接儲存著它的值,而引用變數儲存著對象(譯註:對象裡儲存著值)的引用。對於參考型別來說,
兩個參考型別的變數可以可以指向同一個對象,因此,會出現在一個引用變數上操作它所指向的對象,卻影響了其他的某個引用變數所指向的對象。
請看例子:
using System;
struct Struct1
{
public int Value;
}
class Class1
{
public int Value = 0;
}
class Test
{
static void Main() {
Struct1 val1 = new Struct1();
Struct1 val2 = val1;
val2.Value = 123;
Class1 ref1 = new Class1();
Class1 ref2 = ref1;
ref2.Value = 123;
Console.WriteLine("Values: {0}, {1}", val1.Value, val2.Value);
Console.WriteLine("Refs: {0}, {1}", ref1.Value, ref2.Value);
}
}
這個例子顯示了兩種類型的區別,程式產生的輸出是:
Values: 0, 123
Refs: 123, 123
給局部變數val2的一個成員賦值,不會影響局部變數val1,因為這兩個局部變數都是實值型別的,並且每個實值型別的變數都有自己的儲存空間。與此相反,賦值操作ref2.Value = 123;影響了ref1和ref2同時指向的那個對象。
注意下面兩條語句:
Console.WriteLine("Values: {0}, {1}", val1.Value, val2.Value);
Console.WriteLine("Refs: {0}, {1}", ref1.Value, ref2.Value);
它們展示了Console.WriteLine方法的字串格式化的功能,用到了可變數量的參數。第一個參數是一個字串,它裡面可以包含數字預留位置如{0}和{1},每一個預留位置指向接下來的某個參數,{0}指向該方法的第二個參數,{1}指向第三個參數,以此類推。在向控制台輸出以前,每一個預留位置都被相應的變數的格式化結果代替(譯註:預留位置裡還可以帶有格式化的指令如{0:C}表示將數字轉換為表示貨幣金額的字串)。
我們可以定義新的enum和struct實值型別,也可以定義class、interface、delegate參考型別。請看例子:
using System;
public enum Color
{
Red, Blue, Green
}
public struct Point
{
public int x, y;
}
public interface IBase
{
void F();
}
public interface IDerived: IBase
{
void G();
}
public class A
{
protected virtual void H() {
Console.WriteLine("A.H");
}
}
public class B: A, IDerived
{
public void F() {
Console.WriteLine("B.F, implementation of IDerived.F");
}
public void G() {
Console.WriteLine("B.G, implementation of IDerived.G");
}
override protected void H() {
Console.WriteLine("B.H, override of A.H");
}
}
public delegate void EmptyDelegate();
例子給出了每一個類型的定義。接下來會詳細介紹這些類型的定義。