[C#] อ่านไฟล์ INI แล้ว set ค่าลงใน Object ตรงๆ [ใช้ Reflection]

ถ้าเรามีไฟล์ INI หรือ อะไรซักอย่างที่เก็บค่า ประมาณ
A = 1
B = 2
แล้วอยากจะดึงขึ้นมาใช้
เราสามารถดึงมันขึ้นมาเก็บไว้ใน MAP หรือ DICTIONARY ได้
แต่จังหวะที่เราจะใช้งาน เราต้องจำชื่อมันเป็น string เพื่อเรียกใช้งาน เช่น map.get(“A”)

แต่ถ้าเรารับค่าจาก INI ด้วย Object ได้ เวลาเราอยากได้ค่าไหน เราก็เรียกใช้ obj.getA() ได้ ซึ่งมันน่าจะช่วยให้เราไม่ต้องไปจำว่ามี string อะไรบ้าง เวลาทำงานก็น่าจะสะดวกกว่า (มั้ง)

VRSTVY=   	1
VRTAKY=   	1
DUPLICATE_DRILL=	1
ORIENT =	1
AU_B  = 	3.868
AU_A  = 	4.194
NEP_MASKA_A= 	YES
BARVA_NM_A= 	GREEN
public class Vyr
{
    public Vyr()
    {
        ReadComplete = false;
    }

    public bool ReadComplete {  get; set; }
    public string VRSTVY { get; set; }
    public string VRTAKY {  get; set; }
    public string DUPLICATE_DRILL { get; set; }
    public string ORIENT { get; set; }
    public string AU_B  { get; set; }
    public int AU_A  { get; set; }
    public int NEP_MASKA_A { get; set; }
    public bool BARVA_NM_A {  get; set; }
}
public class VyrReader
{
    public string VyrFileName { get; set; }

    public Vyr readVbr()
    {
        if (!System.IO.File.Exists(VyrFileName))
        {
            throw new Exception("File VYR is not exists, Please check before continue");
        }
        Vyr vyr = new Vyr();
        vyr.InputFileName = VyrFileName;

        using (StreamReader reader = new StreamReader(VyrFileName))
        {
            string line;
            while ((line = reader.ReadLine()) != null)
            {
                if (line.StartsWith("#")) continue;

                //Console.WriteLine(decryptedString);
                Match match = Regex.Match(line.Trim(), @"(.*)\s*=\s*(.*)");
                if (match.Success)
                {

                    string propertyName = match.Groups[1].Value.Trim().Replace(" ", "_");
                    string propertyValue = match.Groups[2].Value.Trim();

                    // 1. ดึงข้อมูล Property ผ่าน Reflection (กำหนดให้ ignore case เพื่อไม่ให้พังเรื่องตัวพิมพ์เล็ก/ใหญ่)
                    PropertyInfo prop = typeof(Vyr).GetProperty(
                        propertyName,
                        BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance
                    );

                    // 2. ถ้าเจอ Property ที่ชื่อตรงกัน ให้เซ็ตค่าลงไป
                    if (prop != null && prop.CanWrite)
                    {
                        Type targetType = Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType;
                        object convertedValue;

                        if (targetType == typeof(bool))
                        {
                            convertedValue = ParseBoolean(propertyValue);
                            //Console.WriteLine($"Prope {propertyName} = {propertyValue} -> {prop.PropertyType} => {convertedValue}");
                        } else
                        {
                            convertedValue = string.IsNullOrWhiteSpace(propertyValue) ? null : Convert.ChangeType(propertyValue, targetType);
                            //Console.WriteLine($"Prope {propertyName} = {propertyValue} -> {prop.PropertyType} => {convertedValue}");
                        }
                        prop.SetValue(vyr, convertedValue, null);
                    } else
                    {
                        Console.WriteLine("Cannot get property for: " + propertyName + " = " + propertyValue);
                    }
                }
            }

        }

        vyr.ReadComplete = true;
        return vyr;
    }

    public static bool ParseBoolean(string input)
    {
        if (string.IsNullOrWhiteSpace(input)) return false;

        switch (input.Trim().ToLower())
        {
            case "yes":
            case "y":
            case "true":
            case "1":
            case "ano":
                return true;

            default:
                return false;
        }
    }
}