views:

114

answers:

3

Hi, 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....

A: 

How about storing it all in a Dictionary<string, string>?

shahkalpesh
Its a bit late now, its a mature code base. Should have done that from the beginning! Thanks for the answer though.
Chris
+5  A: 

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));
John Feminella
+4  A: 

If they are properties in your class you can use:

this.GetType().GetProperty(fieldName).SetValue(this, value, null);

A field in the class

this.GetType().GetField(fieldName).SetValue(this, value, null);

You may need to alter binding flags based on the public/private status of the fields.

If they're just local variables to a function like you've described however I believe you may be out of luck.

It's by far preferable to use a datatype designed to be used in this way like a Dictionary, and perhaps you should consider replacing the existing variables with Properties that reference the dictionary. EG: string a { get { return myDictionary["a"]; } }. This may let you keep backwards compatibility without resorting to reflection, which really should be a last resort.

Tim Schneider