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

ความแตกต่างระหว่าง var และ dynamic ใน C#

ความแตกต่างหลัก: Static vs Dynamic Typing

คุณสมบัติvar (Implicitly Typed)dynamic
Type ResolutionCompile-time (Static)Runtime (Dynamic)
Type Inferenceจาก Initializer Expressionจาก Runtime Value
Initializationบังคับ ต้อง Initialize ทันทีไม่บังคับ (สามารถเป็น null/เปลี่ยน Type ได้)
Type SafetyFull Compile-time CheckingNo Compile-time Checking
IntelliSense✅ Full Support❌ ไม่มี
Refactoring✅ Safe❌ Risky
PerformanceFast (Direct Call)Slow (DLR Dispatch)
IntroducedC# 3.0C# 4.0
Underlying TypeStatic Type (เช่น int, string, List<T>)System.Object (Dynamic Wrapper)

var - Implicitly Typed Local Variable


// Compiler Infers Type จาก Right-hand Side
var name = "John";           // string
var age = 30;                // int
var numbers = new List(); // List
var person = new Person();   // Person
var result = GetData();      // Return Type ของ GetData()

// ❌ Error: ไม่มี Initializer
// var x; 

// ❌ Error: Null ไม่มี Type Info
// var x = null;

// ✅ OK: Explicit Cast
var x = (string)null;

dynamic - Dynamically Typed


dynamic dyn = "Hello";
Console.WriteLine(dyn.Length); // 5 (Runtime: string.Length)

dyn = 123;
Console.WriteLine(dyn + 10);   // 133 (Runtime: int + int)

// ไม่มี Compile-time Check
dyn.NonExistentMethod(); // ✅ Compile OK, ❌ Runtime: RuntimeBinderException

// ใช้กับ COM, JSON, Dynamic Objects
dynamic json = JObject.Parse("{ 'name': 'John' }");
Console.WriteLine(json.name); // John

ตัวอย่างเปรียบเทียบ


class Program
{
    static void Main()
    {
        // VAR - Static Typing
        var list = new List { "A", "B" };
        list.Add("C"); // ✅ IntelliSense OK
        // list.Add(123); // ❌ Compile Error: int → string
        
        // DYNAMIC - Dynamic Typing
        dynamic dynList = new List { "A", "B" };
        dynList.Add("C");     // ✅ Runtime OK
        dynList.Add(123);     // ✅ Compile OK, Runtime OK (List behavior)
        dynList.FooBar();     // ✅ Compile OK, ❌ Runtime Exception
        
        // Performance
        var sw = Stopwatch.StartNew();
        for (int i = 0; i < 100000; i++) 
        {
            var v = i.ToString(); // var
        }
        Console.WriteLine($"var: {sw.ElapsedMs}ms");
        
        sw.Restart();
        for (int i = 0; i < 100000; i++) 
        {
            dynamic d = i.ToString(); // dynamic
        }
        Console.WriteLine($"dynamic: {sw.ElapsedMs}ms"); // ช้ากว่า 10-100x
    }
}


เมื่อไหร่ใช้ var

  • ✅ Default Choice สำหรับ Local Variables
  • ✅ Type ชัดเจนจาก RHS (Constructor, Factory, Cast)
  • ✅ Anonymous Types: var anon = new { Name = "John", Age = 30 };
  • ✅ LINQ Queries: var query = from x in list where x > 5 select x.Name;
  • ✅ Complex Generic Types: var dict = new Dictionary>();

เมื่อไหร่ใช้ dynamic

  • ✅ COM Interop (Office, Legacy ActiveX)
  • ✅ Dynamic Languages (IronPython, JavaScript)
  • ✅ JSON/XML Ad-hoc Parsing (JObject, XElement)
  • ✅ Plugin/Scripting Systems
  • ✅ Reflection-heavy Code Simplification

เมื่อไหร่ ไม่ควร ใช้ dynamic

  • ❌ General Purpose Variables
  • ❌ Public API / Method Parameters / Return Types
  • ❌ Performance Critical Paths
  • ❌ Domain Models / DTOs / Entities
  • ❌ ที่มี Strong Type Alternative (Records, JsonSerializer, Source Generators)

Modern Alternatives to dynamic


// 1. System.Text.Json.Nodes (DOM API)
JsonNode node = JsonNode.Parse(json);
string name = node["name"]!.GetValue();

// 2. JsonSerializer + Anonymous Type (Deserialize to Shape)
var shape = new { Name = "", Age = 0 };
var data = JsonSerializer.Deserialize(json, shape.GetType());

// 3. Source Generators (Compile-time JSON Types)
// 4. Records + Pattern Matching
if (person is { Name: "Admin", Age: > 18 }) { ... }