开发者

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 = ..开发者_如何学Python.
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 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));


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.


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜