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();
列舉了每種類型聲明的示例。後面幾節將闡明關於類型聲明的細節。