dynamic Keyword คืออะไร?
บอก Compiler: "Skip Compile-time Type Checking, ตรวจสอบตอน Runtime แทน"
- Static Typed Language (C#) → Dynamic Behavior
- Type Resolution เลื่อนไป Runtime (DLR - Dynamic Language Runtime)
- Syntax Errors → Runtime Errors (Exception)
- IntelliSense ไม่ทำงาน
ตัวอย่างพื้นฐาน
using System;
class Program
{
static void Main()
{
dynamic dyn = 100;
Console.WriteLine($"Value: {dyn}, Type: {dyn.GetType()}");
// Value: 100, Type: System.Int32
dyn = "Hello World!!";
Console.WriteLine($"Value: {dyn}, Type: {dyn.GetType()}");
// Value: Hello World!!, Type: System.String
dyn = true;
Console.WriteLine($"Value: {dyn}, Type: {dyn.GetType()}");
// Value: True, Type: System.Boolean
dyn = DateTime.Now;
Console.WriteLine($"Value: {dyn}, Type: {dyn.GetType()}");
// Value: 1/1/2024, Type: System.DateTime
// เรียก Method/Property ที่ไม่มีจริง → RuntimeBinderException
// dyn.NonExistentMethod(); // Runtime Error!
Console.ReadLine();
}
}
Output
Value: 100, Type: System.Int32 Value: Hello World!!, Type: System.String Value: True, Type: System.Boolean Value: 1/1/2024 10:30:00 AM, Type: System.DateTime
เมื่อไหร่ควรใช้ dynamic
| Scenario | ตัวอย่าง |
|---|---|
| COM Interop (Office, Legacy) | Excel/Word Automation, ไม่ต้อง Reference PIAs |
| Dynamic Language Interop | IronPython, IronRuby, JavaScript (Jint) |
| JSON/XML Parsing แบบ Ad-hoc | JObject, XElement Dynamic Access |
| Reflection-Heavy Code | ลด Boilerplate GetProperty/SetValue |
| Plugin/Scripting System | User Scripts ที่ Type ไม่ทราบ Compile-time |
ตัวอย่าง: JSON Parsing กับ Newtonsoft.Json
using Newtonsoft.Json.Linq;
string json = @"{ ""name"": ""John"", ""age"": 30, ""address"": { ""city"": ""Bangkok"" } }";
dynamic data = JObject.Parse(json);
Console.WriteLine(data.name); // John
Console.WriteLine(data.age); // 30
Console.WriteLine(data.address.city); // Bangkok
// เพิ่ม Property ใหม่
data.email = "john@email.com";
Console.WriteLine(data.ToString());
⚠️ ข้อเสียและความเสี่ยง
Performance: DLR Cache ช่วยแต่ช้ากว่า Static ~10-100x
No IntelliSense: ไม่มี Autocomplete, Refactoring, Compile-time Check
Runtime Errors: Typo ใน Property Name → Runtime Exception
No Null Safety: Compiler ไมーチ่วย Nullable Analysis
Boxing: Value Types ถูก Box ทุกครั้ง
No IntelliSense: ไม่มี Autocomplete, Refactoring, Compile-time Check
Runtime Errors: Typo ใน Property Name → Runtime Exception
No Null Safety: Compiler ไมーチ่วย Nullable Analysis
Boxing: Value Types ถูก Box ทุกครั้ง
Alternatives (ดีกว่าในหลายกรณี)
1. System.Text.Json (C# Modern)
// Strongly Typed
var person = JsonSerializer.Deserialize<Person>(json);
// Anonymous Type (Quick)
var anon = JsonSerializer.Deserialize<dynamic>(json); // ยังใช้ dynamic
// JsonNode / JsonElement (Low-level, No Class Needed)
using System.Text.Json.Nodes;
var node = JsonNode.Parse(json);
string name = node["name"]!.GetValue<string>();
2. ExpandoObject (Dynamic Dictionary)
using System.Dynamic;
dynamic expando = new ExpandoObject();
expando.Name = "John";
expando.Age = 30;
expando.SayHello = new Action(() => Console.WriteLine($"Hi {expando.Name}"));
expando.SayHello(); // Hi John
3. Records + Pattern Matching (Type-Safe)
record Person(string Name, int Age, Address Address);
record Address(string City, string Country);
// Pattern Matching แทน Dynamic Navigation
if (person is { Address.City: "Bangkok" }) { ... }
สรุป
- ✅ ใช้ dynamic: COM, Dynamic Languages, Quick JSON Exploration
- ❌ หลีกเลี่ยง: Business Logic, Public API, Performance Critical, General Purpose
- 🔧 Modern Alternative:
System.Text.Json.Nodes,JsonElement, Records, Source Generators