问题
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....
回答1:
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));
回答2:
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.
回答3:
How about storing it all in a Dictionary<string, string>
?
来源:https://stackoverflow.com/questions/2091190/accessing-an-instance-variable-by-name-string-kinda-like-dynamic-languages-do