Search code examples
c#reflectiondynamic-languages

Accessing an instance variable by name (string), kinda like dynamic languages do, in C#


i've got some C# code like this:

string fieldName = ...
string value = ...

if (fieldName == "a") a = value;
if (fieldName == "b") b = value;
if (fieldName == "c") c = value;
if (fieldName == "d") d = value;
...

I want something like this:

string fieldName = ...
string value = ...

SetMyInstanceVariable(fieldName, value);
...

Is there a simple way to do it? I know that given a class's name in a string, you can instantiate it with System.Activator, and this is kindof similar so i was hoping....


Solution

  • A Dictionary<string, string> is the easiest approach:

    public class Bag {
      var props = new Dictionary<string, string>();
    
      // ...
    
      public string this[string key] {
        get { return props[key]; }
        set { props[key] = value; }
      }
    }
    

    The reflection approach is considerably more complex but still doable:

    public class Fruit {
      private int calories = 0;
    }
    
    // ...
    
    var f = new Fruit();
    Type t = typeof(Fruit);
    
    // Bind to a field named "calories" on the Fruit type.
    FieldInfo fi = t.GetField("calories",
      BindingFlags.NonPublic | BindingFlags.Instance);
    
    // Get the value of a field called "calories" on this object.
    Console.WriteLine("Field value is: {0}", fi.GetValue(f));
    
    // Set calories to 100. (Warning! Will cause runtime errors if types
    // are incompatible -- try using "100" instead of the integer 100, for example.)
    fi.SetValue(f, 100);
    
    // Show modified value.
    Console.WriteLine("Field value is: {0}", fi.GetValue(f));