[C#] How to Set Property Values Dynamically by Name Using Reflection

When loading data from external files (such as CSVs or configuration files) or dealing with dynamically determined keys, you often need to set object property values based on string names.

The SetValue method in Reflection is incredibly useful for this purpose. It allows you to write values to properties by specifying their names as strings at runtime, even if those names are unknown at compile time.

目次

Setting Property Values Dynamically

The following sample code demonstrates how to populate an application configuration class (AppConfiguration) by specifying property names and values dynamically.

Sample Code

using System;
using System.Reflection;

public class Program
{
    public static void Main()
    {
        // 1. Create the target instance
        var config = new AppConfiguration();

        Console.WriteLine("--- Before Settings ---");
        Console.WriteLine(config);

        // 2. Set values using Reflection
        // Normal assignment: config.Resolution = "1920x1080";
        SetDynamicProperty(config, "Resolution", "1920x1080");
        SetDynamicProperty(config, "MaxFrameRate", 60);
        SetDynamicProperty(config, "EnableShadows", true);

        // Test with a non-existent property name
        SetDynamicProperty(config, "UnknownSetting", 123);

        Console.WriteLine("\n--- After Settings ---");
        Console.WriteLine(config);
    }

    /// <summary>
    /// Sets a value to a property of a specified object
    /// </summary>
    /// <param name="target">Target object</param>
    /// <param name="propertyName">Property name</param>
    /// <param name="newValue">Value to set</param>
    public static void SetDynamicProperty(object target, string propertyName, object newValue)
    {
        if (target == null) return;

        // 1. Get object type information
        Type type = target.GetType();

        // 2. Get property information for the specified name
        PropertyInfo propInfo = type.GetProperty(propertyName);

        // Stop processing if the property does not exist
        if (propInfo == null)
        {
            Console.WriteLine($"[Warning] Property '{propertyName}' does not exist.");
            return;
        }

        // 3. Check if writable (does a setter exist?)
        if (!propInfo.CanWrite)
        {
            Console.WriteLine($"[Warning] Property '{propertyName}' is not writable.");
            return;
        }

        try
        {
            // 4. Set the value
            // 1st arg: Target instance, 2nd arg: Value to set, 3rd arg: Index (usually null)
            propInfo.SetValue(target, newValue);
            Console.WriteLine($"[Success] Set {propertyName} to {newValue}.");
        }
        catch (ArgumentException)
        {
            Console.WriteLine($"[Error] Failed to set value for {propertyName} (Type mismatch, etc.).");
        }
    }
}

// Application Configuration Class
public class AppConfiguration
{
    public string Resolution { get; set; } = "800x600"; // Resolution
    public int MaxFrameRate { get; set; } = 30;         // FPS
    public bool EnableShadows { get; set; } = false;    // Shadows

    public override string ToString()
    {
        return $"[Config] Resolution:{Resolution}, FPS:{MaxFrameRate}, Shadows:{EnableShadows}";
    }
}

Explanation and Technical Points

1. PropertyInfo.SetValue Method

By using the SetValue method on the PropertyInfo object obtained via GetProperty, you can invoke the setter of the target instance.

  • Arguments: The basic form is SetValue(object obj, object value). For indexed properties, a third argument is used.
  • Type Consistency: The type of the value passed must be compatible with the property’s type. For example, trying to pass a string to an int property will throw an ArgumentException (automatic type conversion is not performed).

2. Checking with the CanWrite Property

Some properties may only have a get accessor (read-only). By checking propInfo.CanWrite before calling SetValue, you can avoid errors caused by attempting to write to read-only properties.

3. Practical Use Case: Data Mappers

This technique is frequently used in the internal implementation of “Data Binding” and “O/R Mappers.” It allows libraries to map database query results (column names and values) or text data like JSON/XML directly to class properties.

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次