C# 支持兩種類型:“值類型”和“引用類型”。值類型包括簡單類型(如 char
、int
和 float
)、枚舉類型和結構類型。引用類型包括類 (Class) 類型、接口類型、委托類型和數組類型。
值類型與引用類型的區別在於值類型的變量直接包含其數據,而引用類型的變量則存儲對象引用。對於引用類型,兩個變量可能引用同一對象,因此對一個變量的操作可能影響另一個變量所引用的對象。對於值類型,每個變量都有自己的數據副本,對一個變量的操作不可能影響另一個變量。
示例
using System; class Class1 { public int Value = 0; } class Test { static void Main() { int val1 = 0; int val2 = val1; val2 = 123; Class1 ref1 = new Class1(); Class1 ref2 = ref1; ref2.Value = 123; Console.WriteLine("Values: {0}, {1}", val1, val2); Console.WriteLine("Refs: {0}, {1}", ref1.Value, ref2.Value); } }
顯示了這種區別。運行該程序,可見下列輸出:
Values: 0
,123
Refs:123
,123
給局部變量 val1
賦值不會影響局部變量 val2
,這是因為兩個局部變量都是值類型(int
類型),每個局部變量都保存著各自的數據。相反,賦值 ref2.Value = 123;
則會影響到 ref2
,因為 ref1
和 ref2
所引用的其實是同一個對象。
應對代碼行
Console.WriteLine("Values: {0}, {1}", val1, val2); Console.WriteLine("Refs: {0}, {1}", ref1.Value, ref2.Value);
做進一步解釋,因為方法 Console.WriteLine
的某些字符串格式化行為較復雜,它所需的參數數目是可變的。第一個參數是字符串,它可能包含類似 {0}
和 {1}
這樣編了號的占位符。每個占位符都引用一個尾隨參數:{0}
引用第二個參數,{1}
引用第三個參數,依此類推。在將輸出發送到控制台之前,每個占位符都會被替換成它所引用的參數的值,並按規定的格式顯示。
開發人員可以通過枚舉聲明和結構聲明定義新的值類型,並可通過類聲明、接口聲明和委托聲明定義新的引用類型。示例
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();
列舉了每種類型聲明的示例。後面幾節將闡明關於類型聲明的細節。