Доступ к переменной экземпляра по имени (строке), как в динамических языках, в C # - PullRequest
0 голосов
/ 19 января 2010

У меня есть некоторый код C #, подобный этому:

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

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

Я хочу что-то вроде этого:

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

SetMyInstanceVariable(fieldName, value);
...

Есть ли простой способ сделать это?Я знаю, что, учитывая имя класса в строке, вы можете создать его экземпляр с помощью System.Activator, и это отчасти похоже, поэтому я надеялся ...

Ответы [ 3 ]

6 голосов
/ 19 января 2010

A Dictionary<string, string> - самый простой подход:

public class Bag {
  var props = new Dictionary<string, string>();

  // ...

  public string this[string key] {
    get { return props[key]; }
    set { props[key] = value; }
  }
}

Подход отражения значительно сложнее, но все же выполнимо:

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));
4 голосов
/ 19 января 2010

Если они являются объектами вашего класса, вы можете использовать:

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

Поле в классе

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

Возможно, вам придется изменить флаги привязки в зависимости от общего / частного статуса полей.

Если они являются просто локальными переменными для функции, как вы описали, тем не менее, я считаю, что вам может не повезти.

Гораздо предпочтительнее использовать тип данных, разработанный для такого использования, как словарь, и, возможно, вам следует подумать о замене существующих переменных свойствами, которые ссылаются на словарь. Например: string a { get { return myDictionary["a"]; } }. Это может позволить вам сохранить обратную совместимость, не прибегая к рефлексии, которая действительно должна быть последним средством.

0 голосов
/ 19 января 2010

Как насчет хранения всего этого в Dictionary<string, string>?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...