Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C#

ตัวแปร Dynamic ใน C# คืออะไร ใช้เมื่อไหร่

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 InteropIronPython, IronRuby, JavaScript (Jint)
JSON/XML Parsing แบบ Ad-hocJObject, XElement Dynamic Access
Reflection-Heavy Codeลด Boilerplate GetProperty/SetValue
Plugin/Scripting SystemUser 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 ทุกครั้ง

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