Доступ к свойству объекта как строка и устанавливание ее значения

У меня есть экземпляр Account класс. Каждый объект учетной записи имеет владельца, ссылку, и т.д.

Одним путем я могу получить доступ, свойства учетных записей через средства доступа как

account.Reference;

но я хотел бы смочь получить доступ к нему с помощью динамических строковых селекторов как:

account["PropertyName"];

точно так же, как в JavaScript. Таким образом, я имел бы account["Reference"] который возвратил бы значение, но я также хотел бы смочь присвоить новое значение после этого как:

account["Reference"] = "124ds4EE2s";

Я заметил, что могу использовать

DataBinder.Eval(account,"Reference") 

для получения свойства на основе строки но использующий это, я не могу присвоить значение свойству.

Какая-либо идея о том, как я мог сделать это?

43
задан Micha Wiedenmann 16 August 2015 в 22:15
поделиться

5 ответов

Вам нужно использовать Отражение:

PropertyInfo property = typeof(Account).GetProperty("Reference");

property.SetValue(myAccount, "...", null);

Обратите внимание, что это будет очень медленно.

1
ответ дан 26 November 2019 в 22:32
поделиться

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

С другой стороны, если вам нужно поддерживать список определяемых пользователем свойств, вы не можете использовать свойства C #. Вам нужно представить, что вы Dictionary , или вам нужно предоставить свойство, которое ведет себя как Dictionary . Вот пример того, как можно сделать так, чтобы класс Account поддерживал определяемые пользователем свойства:

public class Account
{
    Dictionary<string, object> properties;
    public object this[string propertyName]
    {
        get
        {
            if (properties.ContainsKey[propertyName])
                return properties[propertyName];
            else
                return null;
        }
        set
        {
            properties[propertyName] = value;
        }
    }
}
1
ответ дан 26 November 2019 в 22:32
поделиться

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

public object this[string propertyName]
{
    get
    {
        if(propertyName == "Reference")
            return this.Reference;
        else
            return null;
    }
    set
    {
        if(propertyName == "Reference")
            this.Reference = value;
        else
            // do error case here            
    }
}

Обратите внимание, что при этом вы теряете безопасность типов.

6
ответ дан 26 November 2019 в 22:32
поделиться

Прежде всего, вам следует избегать этого; C # - это язык со строгой типизацией, поэтому воспользуйтесь преимуществами безопасности типов и производительности, которые сопровождают этот аспект.

Если у вас есть законная причина для получения и установки значения свойства динамически (другими словами, когда тип и / или имя свойства не могут быть определены в коде), вам придется использовать отражение.

Наиболее инлайн-вариант выглядит так:

object value = typeof(YourType).GetProperty("PropertyName").GetValue(yourInstance);
...
typeof(YourType).GetProperty("PropertyName").SetValue(yourInstance, "value");

Однако вы можете кэшировать объект PropertyInfo , чтобы сделать его более читабельным:

System.Reflection.PropertyInfo prop = typeof(YourType).GetProperty("PropertyName");

object value = prop.GetValue(yourInstance);
...
prop.SetValue(yourInstance, "value");
68
ответ дан 26 November 2019 в 22:32
поделиться

Вы можете попытаться объединить индексатор с отражением ...

public object this[string propertyName]
{
    get
    {
        PropertyInfo property = GetType().GetProperty(propertyName);
        return property.GetValue(this, null);
    }
    set
    {
        PropertyInfo property = GetType().GetProperty(propertyName);
        property.SetValue(this,value, null);
    }
}
32
ответ дан 26 November 2019 в 22:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: