變數 是程式操作資料的具名儲存位置。C# 是強型別語言,每個變數有固定型別,決定記憶體大小、配置位置、允許操作。掌握變數宣告、初始化、作用域、型別分類,是寫出正確程式的基石。
// 基本宣告:型別 變數名;
int score;
string name;
double price;
// 宣告並初始化
int count = 0;
string title = "C# Guide";
var pi = 3.14159; // 型別推斷 (C# 3+)
// 多變數宣告 (同型別)
int x = 1, y = 2, z = 3;
var (a, b) = (10, 20); // 元組解構 (C# 7+)
// 預設值運算子
int defaultInt = default; // 0
string defaultString = default; // null
var defaultStruct = default(MyStruct); // 結構體預設值
var 讓編譯器從初始化運算式推斷型別:
var i = 42; // int
var s = "hello"; // string
var list = new List(); // List
var anon = new { Name = "Alice", Age = 30 }; // 匿名型別
// 限制:
// - 必須初始化
// - 不能為 null (無法推斷)
// - 不能用於欄位/屬性/參數/回傳型別
// - 不能在宣告前使用
| 分類 | 型別範例 | 記憶體配置 | 指派行為 | 預設值 |
|---|---|---|---|---|
| 實值型別 | int, double, bool, char, struct, enum, DateTime | 堆疊 / 內嵌 | 複製值 | 全 0 / false / '\0' |
| 參考型別 | class, string, array, delegate, interface, object | 堆積 | 複製參考 | null |
| 可為 Null 實值型別 | int?, bool?, DateTime? | 堆疊 (包裝) | 複製值 | null (HasValue=false) |
sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, boolstruct (含 DateTime, TimeSpan, Guid 等)enum (底層為整數)(int, string) (C# 7+)class、record、object、stringinterfaceint[], string[,]Action, Func<T>, 自訂委派dynamic (延遲繫結)方法/建構子/屬性/索引子/事件存取子/區域函數內宣告:
void Method() {
int x = 1; // 進入方法配置,離開方法釋放 (實值型別)
if (true) {
int y = 2; // 區塊作用域,僅在 {} 內可見
}
// y 不可見
for (int i = 0; i < 10; i++) { // i 作用域限於 for
var z = i * 2;
}
}
類別/結構體直接宣告:
static,應用程式域生命週期,靜態建構子前初始化const,編譯期常數,隱含 staticreadonly,建構子/宣告初始化ref,共用儲存位置out,必須指派in,禁止修改params,可變參數C# 運算式分為兩類:
| 類型 | 定義 | 範例 | 可指派 |
|---|---|---|---|
| Lvalue | 參考儲存位置的運算式,可出現在指派左邊 | 變數、屬性、索引子、陣列元素、ref 回傳 | 是 |
| Rvalue | 代表值的運算式,只能出現在指派右邊 | 字面值、方法呼叫、運算子運算式、常數 | 否 |
int a = 10; // a 是 Lvalue, 10 是 Rvalue
a = 20; // OK
// 10 = a; // 錯誤:Rvalue 不能在左邊
a + b = 30; // 錯誤:a+b 是 Rvalue
arr[0] = 5; // OK:索引子是 Lvalue
DateTime.Now = DateTime.MinValue; // 錯誤:屬性唯讀 (無 setter)
| 類型 | 慣例 | 範例 |
|---|---|---|
| 區域變數/參數 | camelCase | firstName, itemCount |
| 私有欄位 | _camelCase 或 camelCase | _firstName, firstName |
| 公開欄位/屬性 | PascalCase | FirstName, ItemCount |
| 常數 | PascalCase | MaxRetries |
| 類型參數 | T 或 TDescriptor | T, TKey |
規則:字母/底線開頭、可含數字/底線、不可為關鍵字 (除非加 @ 前綴)、區分大小寫。
// 元組解構
var (name, age) = GetPerson(); // 宣告多變數
// 物件解構 (需 Deconstruct 方法)
var (x, y) = point; // Point.Deconstruct(out x, out y)
// 模式比對宣告 (C# 7+)
if (obj is int i) { /* i 為區域變數 */ }
if (input is string { Length: > 0 } s) { /* s 為區域變數 */ }
// switch 運算式宣告
var result = input switch {
int i => i * 2,
string s => s.Length,
_ => 0
};
var:型別明顯時 (new List、字面值);型別不明顯時寫明型別。var 是動態型別嗎?A: 不是。var 是靜態型別推斷,編譯期決定型別,執行期不可變。dynamic 才是動態型別。
A: 所有欄位遞歸設為 0/null/false。無參數建構子不存在 (C# 10 前),default(T) 產生全零實例。
A: 32 位元程序 4 bytes,64 位元程序 8 bytes (指標大小)。物件本身在堆積另行配置。
ref 區域變數?A: 需要修改陣列元素、ref 回傳值、或避免大型結構體複製時。