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

วิธีตั้งค่า Property ที่มี Data Type ต่างกันด้วยค่า String ผ่าน Reflection ใน C#

Reflection คือเมื่อ Managed Code สามารถอ่าน Metadata ของตัวเองเพื่อหา Assemblies โดยพื้นฐานแล้วมันอนุญาตให้โค้ดตรวจสอบโค้ดอื่นภายในระบบเดียวกัน ใน C# Reflection เราสามารถสร้างอินสแตนซ์ของ Type แบบ Dynamic และ Bind Type นั้นกับออบเจกต์ที่มีอยู่แล้ว นอกจากนี้ เรายังสามารถรับ Type จากออบเจกต์ที่มีอยู่และเข้าถึง Properties ของมันได้ เมื่อเราใช้ Attributes ในโค้ด Reflection ให้การเข้าถึงได้ เนื่องจากมันจัดเตรียมออบเจกต์ของ Type ที่อธิบาย Modules, Assemblies และ Types

สมมติว่าเรามี Property ประเภท double และใน Runtime เรามีค่าเป็น String และต้องการ Assign ให้ Property หลังจากเปลี่ยน Type แล้ว เราสามารถใช้ Convert.ChangeType() - มันอนุญาตให้เราใช้ข้อมูล Runtime บน Type ใดๆ ที่ implement IConvertible เพื่อเปลี่ยนรูปแบบการแสดงผล

ตัวอย่าง

using System;
using System.Reflection;

namespace DemoApplication {
    class Program {
        static void Main() {
            Circle circle = new Circle();
            string value = "6.5";
            
            PropertyInfo propertyInfo = circle.GetType().GetProperty("Radius");
            
            // แปลง String เป็น Type ของ Property (double) แล้ว Set ค่า
            propertyInfo.SetValue(circle, Convert.ChangeType(value, propertyInfo.PropertyType), null);
            
            var radius = circle.GetType().GetProperty("Radius").GetValue(circle, null);
            Console.WriteLine($"Radius: {radius}");
            Console.ReadLine();
        }
    }
    
    class Circle {
        public double Radius { get; set; }
    }
}

Output

Radius: 6.5

ในตัวอย่างข้างต้น เราเห็นว่าค่า String "6.5" ถูกแปลงเป็น Type จริงคือ double โดยใช้ Convert.ChangeType และ Assign ให้ Property Radius ผ่าน Reflection ใน Runtime

กรณีที่ซับซ้อนกว่า: Enum และ Custom Types

public enum Status { Active = 1, Inactive = 2, Pending = 3 }

public class User {
    public Status UserStatus { get; set; }
    public DateTime CreatedDate { get; set; }
}

class Program {
    static void Main() {
        User user = new User();
        
        // Set Enum จาก String
        string statusStr = "Active";
        PropertyInfo statusProp = user.GetType().GetProperty("UserStatus");
        object statusValue = Enum.Parse(statusProp.PropertyType, statusStr);
        statusProp.SetValue(user, statusValue);
        
        // Set DateTime จาก String
        string dateStr = "2024-01-15";
        PropertyInfo dateProp = user.GetType().GetProperty("CreatedDate");
        object dateValue = Convert.ChangeType(dateStr, dateProp.PropertyType);
        dateProp.SetValue(user, dateValue);
        
        Console.WriteLine($"Status: {user.UserStatus}");
        Console.WriteLine($"CreatedDate: {user.CreatedDate}");
    }
}

ข้อควรระวัง

  • Convert.ChangeType ทำงานได้เฉพาะ Type ที่ implement IConvertible (Primitive types, DateTime, Decimal, Enum ฯลฯ)
  • สำหรับ Custom Class/Struct ต้องใช้ TypeConverter หรือ Custom Parsing Logic
  • ควร Wrap ใน Try-Catch เพื่อจัดการ Exception เมื่อแปลงไม่สำเร็จ
  • Performance: Reflection ช้ากว่าการเข้าถึง Property โดยตรง ควร Cache PropertyInfo ไว้ใช้ซ้ำ