新手概念 · 型別
C# 裡 var 與顯式型別
最常見的誤解:var 不是動態型別。變數依然有唯一的型別,由編譯器從等號右邊挑出來——只是你沒親筆寫下它。
var 到底做了什麼
型別來自右邊,在編譯期決定。Visual Studio 裡這個程式會列印型別——而且從此再也不變:
var price = 9.99; // double —— 因為 9.99 是 double 字面量
var count = 42; // int —— 因為 42 是 int 字面量
var name = "Ada"; // string
Console.WriteLine(price.GetType()); // System.Double
Console.WriteLine(count.GetType()); // System.Int32
Console.WriteLine(name.GetType()); // System.String
(.GetType() 反射不在瀏覽器引擎的教學子集裡——下面的論斷用能在引擎裡跑的檢查來驗證。)
引擎嚴格的型別檢查能在現場證明同一件事——var 變數的行為和它的推斷型別一模一樣:
var x = 9.99; // 從這一行起 x 就是 double
int y = x; // CS0266: 和你寫的 'double x = 9.99;' 一模一樣
如果 var 是動態的(像 JavaScript),這個賦值早就編譯過了。它沒有——因為 x 是貨真價實的 double,只是被推斷出來而已。
第一天就該知道的兩個字面量陷阱
var a = 7 / 2.0; // double: 3.5
var b = 7 / 2; // int: 3 —— 整數除法,小數沒了!
Console.WriteLine(a);
Console.WriteLine(b);
var 忠實地繼承表示式產出的東西——包括整數除法的意外(完整故事:為什麼 7 / 2 是 3)。
var 的高光時刻
當型別在同一行裡已經一目瞭然時用 var——那它就是純粹的降噪:
var names = new List<string>(); // 顯然是 List<string>
var dog = new Dog("Rex", 3); // 顯然是 Dog
var total = price * quantity; // 型別簡單時也行
泛型容器是最能感受它的地方——對比:
Dictionary<string, List<int>> scores = new Dictionary<string, List<int>>(); // 寫了兩遍
var scores2 = new Dictionary<string, List<int>>(); // 只寫一遍
var scores = new Dictionary>();
scores["Ada"] = new List { 90, 85 };
Console.WriteLine($"Ada has {scores["Ada"].Count} scores");
顯式型別什麼時候贏
當型別是讀者無法從別處得知的資訊時,寫出來:
- 數值意圖:
double average = total / count;表明你期待小數。var average = total / count;會在兩個 int 相除時悄悄繼承 int——披著偽裝的 bug。 - API 返回值:
var user = GetUser(id);逼著讀者懸停或跳轉。User user = GetUser(id);自解釋。 - 長得像的型別:錢用
decimal還是double——差別重要,而 var 把它藏了。
var label = "count: ";
int n = 5;
Console.WriteLine(label + n); // 沒問題:string + int 拼接
var wrong = n = label; // 故意寫的胡話:把 string 塞進 int 槽
var 必須遵守的規矩
- 必須有初始值——
var x;非法(x 是什麼型別?)。 - 之後不能換型別——推斷完就釘死,和任何宣告一樣。
- 它不是 JavaScript 的
var,也不是dynamic——C# 的dynamic是另一個(罕見)關鍵字,跳過編譯期檢查。
團隊慣例,壓縮成一張表
| 場景 | 用 | 為什麼 |
|---|---|---|
同一行有 new | var | 型別已經在右邊寫過了 |
| 數值宣告 | 顯式 | int 還是 double 是承重資訊 |
| 方法呼叫的結果 | 顯式(或好名字) | 讀者不該被迫去查 |
| LINQ / 複雜泛型 | var | 完整型別名比邏輯本身還長 |
大多數風格指南(包括微軟自己的)落在同一句話:右邊能讓型別一目瞭然時用 var,否則寫出來。兩個老手吵起來,吵的幾乎全是"什麼算一目瞭然"。