String для имени переменной

У меня есть класс (Customer), который содержит более 200 строковых переменных как свойство. Я использую метод с параметром ключа и значения. Я пытаюсь предоставить ключ и значение из xml файла. Для этого значение должно быть заменено свойством класса Customer (строковые переменные).

т

Customer
{
  public string Name{return _name};

  public string Address{return _address};
}


CallInput
{
  StringTempelate tempelate = new StringTempelate();
  foreach(item in items)
  tempelate .SetAttribure(item.key, item.Value -->   //Say this value is Name, so it has to substitute Customer.Name
}

Возможно ли это?

Ответы

Ответ 1

Вы можете использовать отражение, чтобы установить свойства "по имени".

using System.Reflection;
...
myCustomer.GetType().GetProperty(item.Key).SetValue(myCustomer, item.Value, null);

Вы также можете прочитать свойства с помощью GetValue или получить список всех имен свойств с помощью GetType(). GetProperties(), который возвращает массив PropertyInfo (свойство Name содержит имя свойства)

Ответ 2

Ну, вы можете использовать Type.GetProperty(name), чтобы получить PropertyInfo, затем вызовите GetValue.

Например:

// There may already be a field for this somewhere in the framework...
private static readonly object[] EmptyArray = new object[0];

...

PropertyInfo prop = typeof(Customer).GetProperty(item.key);
if (prop == null)
{
    // Eek! Throw an exception or whatever...
    // You might also want to check the property type
    // and that it readable
}
string value = (string) prop.GetValue(customer, EmptyArray);
template.SetTemplateAttribute(item.key, value);

Обратите внимание: если вы это сделаете, вы можете захотеть преобразовать свойства в экземпляры делегатов Func<Customer, string> - это будет намного быстрее, но сложнее. Для получения дополнительной информации см. Сообщение моего блога о создании делегатов через отражение.

Ответ 3

Отражение - это вариант, но 200 свойств - это... много. Как бы то ни было, я сейчас работаю над чем-то подобным, но классы создаются с помощью code-gen. Чтобы соответствовать "по имени", я добавил индексатор (на этапе генерации кода):

public object this[string propertyName] {
    get {
        switch(propertyName) {
            /* these are dynamic based on the the feed */
            case "Name": return Name;
            case "DateOfBirth": return DateOfBirth;
            ... etc ...
            /* fixed default */
            default: throw new ArgumentException("propertyName");
        }
    }
}

Это дает удобство "по имени", но хорошая производительность.

Ответ 4

Используйте отражение и объект словаря как свою коллекцию элементов.

Dictionary<string,string> customerProps = new Dictionary<string,string>();
Customer myCustomer = new Customer(); //Or however you're getting a customer object

foreach (PropertyInfo p in typeof(Customer).GetProperties())
{
    customerProps.Add(p.Name, p.GetValue(customer, null));
}