// 源碼
var i = 0;
var flag = true;
var name = "Henllyee";
// 編譯後 IL .locals init
// [0] int32 i
// [1] bool flag
// [2] string name
var 本質上不改變類型系統,編譯器根據初始化表達式靜態推斷,生成 IL 與顯式聲明完全一致。
var list = new List { 1, 2, 4, 100 };
foreach (var item in list)
Console.Write(item + ", ");
// item 類型為 int,無需手寫
var x; ❌)var x = null; ❌)
public static class ObjectExtensions
{
public static string DisplayDefiningAssembly(this object obj)
{
var type = obj.GetType();
var asm = Assembly.GetAssembly(type);
return $"{type.Name} lives here:\n\t{asm}";
}
}
this 指定擴展類型
var ds = new DataSet();
Console.WriteLine(ds.DisplayDefiningAssembly());
// 輸出類似:
// DataSet lives here:
// System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
痛點:自定義命名空間的擴展方法需顯式 using,易遺漏。解決方案:將擴展類放入目標類型所在命名空間(如 System),實現「零引入自動可用」。
// HenllyeeExtensions.cs
namespace System // 關鍵:放入 System 命名空間
{
public static class HenllyeeExtensions
{
public static void Foo(this int i, string msg)
=> Console.WriteLine($"{i} called Foo() say '{msg}'");
}
}
// Program.cs - 無需 using System 即可直接調用
int i = 0;
i.Foo("Hello, Henllyee!"); // 智能提示自動出現
// 輸出:0 called Foo() say 'Hello, Henllyee!'
| 策略 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|
| 放入 System/BCL 命名空間 | 零 using 自動可用,發現性極強 | 污染核心命名空間,可能衝突,官方不推薦大量使用 | 極通用的基礎擴展(如 ToInt32、IsNullOrEmpty) |
| 專用命名空間 + 全局 using | 可控、無污染、現代 C# 支持 global using | 需項目級配置 | 企業級項目、模塊化架構 |
| 按需 using | 意圖明確、無副作用 | 易遺漏、重複引入 | 小項目、臨時腳本 |
var 讓類型聲明「按需推斷」,擴展方法讓類型能力「按需擴展」。兩者結合,配合合理的命名空間策略,能構建出可發現、可組合、低樣板的現代 C# 代碼風格。核心原則:var 用於明顯可推斷處,擴展方法用於輔助增強,命名空間組織服務於發現性與隔離性的平衡。