細聽 Anders Hejlsberg (C# 之父) 在 PDC 2008 的《The Future of C#》演講,梳理 C# 4.0 完整特性地圖。
VS 2008 對應 .NET 3.5 / C# 3.0 / CLR 2.0 — 版本號混亂。VS 2010 統一為 4.0 (CLR 4.0、.NET 4、C# 4、VB 10),CLR 3 成為歷史術語。
// 反射寫法 (C# 3.0)
object calc = GetCalculator();
int sum = (int)calc.GetType().InvokeMember("Add", BindingFlags.InvokeMethod, null, new object[]{10,20});
// dynamic 寫法 (C# 4.0)
dynamic calc = GetCalculator();
int sum = calc.Add(10, 20); // 執行期繫結,支援 COM、IronPython、DOM、反射
var py = Python.CreateRuntime();
dynamic hello = py.UseFile("helloworld.py");
Console.WriteLine("helloworld.py loaded!");
public abstract class DynamicObject : IDynamicObject {
public virtual object GetMember(GetMemberBinder info) { ... }
public virtual object SetMember(SetMemberBinder info, object value) { ... }
public virtual object Invoke(InvokeBinder info, object[] args) { ... }
public virtual object InvokeMember(InvokeMemberBinder info, object[] args) { ... }
public virtual object CreateInstance(CreateInstanceBinder info, object[] args) { ... }
public virtual object GetIndex(GetIndexBinder info, object[] indices) { ... }
public virtual object SetIndex(SetIndexBinder info, object[] indices, object value) { ... }
public virtual object DeleteIndex(DeleteIndexBinder info, object[] indices) { ... }
public virtual object UnaryOperation(UnaryOperationBinder info) { ... }
public virtual object BinaryOperation(BinaryOperationBinder info, object arg) { ... }
public virtual object Convert(ConvertBinder info) { ... }
public MetaObject GetMetaObject() { ... }
}
編譯器層面特性,VB 早有,社群呼聲高納入。
// 定義
public StreamReader OpenTextFile(string path,
Encoding encoding = null,
bool detectEncoding = true,
int bufferSize = 1024);
// 呼叫:命名參數可跳過順序、僅指定關心者
OpenTextFile("foo.txt", Encoding.UTF8, bufferSize: 4096);
OpenTextFile(bufferSize: 4096, path: "foo.txt", detectEncoding: false);
| 改進點 | 說明 |
|---|---|
| Automatic object → dynamic mapping | COM `object` 參數/回傳自動視為 `dynamic`,免強轉 |
| Optional & named parameters | 消除大量 `ref missing` |
| Indexed properties | 支援 `obj[0]` 語法對應 COM 索引屬性 |
| Optional "ref" modifier | 呼叫 COM `ref` 參數可省略 `ref` 關鍵字 |
| Interop type embedding (No PIA) | 編譯器僅嵌入實際使用的 COM 型別元資料,免部署巨大 PIA |
解決 `IList<string> → IList<object>` 型別安全難題。
// 協變:out T (僅輸出位置) — 子轉父安全
public interface IEnumerable<out T> { IEnumerator<T> GetEnumerator(); }
// 逆變:in T (僅輸入位置) — 父轉子安全
public interface IComparer<in T> { int Compare(T left, T right); }
編譯器開放 API,支援執行期動態編譯執行字串程式碼,類似 JavaScript `eval`。Anders Demo:<30 行打造 C# REPL,支援定義函數、動態建立 WinForm + Button,展示極致動態能力。
C# 4.0 以 `dynamic` 拥抱動態世界,以協變逆變修補泛型剛性,以命名/選用參數與 No-PIA 徹底簡化 COM 互操作,以 Compiler-as-Service 開啟元程式設計大門——這版本確立了現代 C#「靜態核心、動態邊界」的雙重身分。