Вопрос по c# – Изменить параметр пользовательского атрибута во время выполнения

12

Мне нужно изменить параметр атрибута во время выполнения. Я упростил свою проблему до простого примера.

Attribute class:

<code>    [AttributeUsage(AttributeTargets.Property)]
    public class MyAttribute : Attribute
    {
        public string Name { get; set; }
    }
</code>

Simple entity wich has decorated properties with attributes:

<code>    public class MyEntity
    {
        [MyAttribute(Name="OldValue1")]
        public string Data1{ get; set; }

        [MyAttribute(Name = "OldValue2")]
        public string Data2 { get; set; }
    }
</code>

Я создал объект класса MyEntity. Я могу изменить значение свойств объекта, но я не могу изменить значение имени свойства атрибута на объектной сущности. Является ли это возможным?

Значение свойства объекта объекта я могу изменить с помощью этой части кода:

<code>                entityProp.SetValue(entity,"NewData",null);
</code>

но я не знаю, как изменить значение свойства Name атрибута на объекте

Это не работа:

<code>attProp.SetValue(attribute,"NewData",null);
</code>

Значение свойства Имя по-прежнему оригинально.

Вот весь тестовый код. Спасибо за помощь.

<code>    [TestMethod]
    public  void Test()
    {
        var entity = new MyEntity
                         {
                             Data1 = "OldData",
                             Data2 = "OldData"
                         };

        PropertyInfo[] entityProps = entity.GetType().GetProperties();

        foreach (var entityProp in entityProps)
        {
            var attribute = Attribute.GetCustomAttribute(entityProp, typeof (MyAttribute)) as MyAttribute;

            if (attribute != null)
            {
                //get attribute’s property NAME
                PropertyInfo attProp= attribute.GetType().GetProperty("Name");

                //get entity property value
                var propertyValue = entityProp.GetValue(entity, null);

                //get attribute’s property NAME value
                var atributeNameValue = attProp.GetValue(entity, null);

                TestContext.WriteLine(string.Format("property name:{0} property value: {1} : atribute name value: {2}\n", 
                    entityProp.Name, propertyValue, atributeNameValue)); 

                //change values
                entityProp.SetValue(entity,"NewData",null);

                //how can I change value of property Name on object entity ?
                attProp.SetValue(attribute,"NewData",null);

            }

        }

        TestContext.WriteLine(string.Format("After change\n"));

        foreach (var entityProp in entityProps)
        {
            var attribute = Attribute.GetCustomAttribute(entityProp, typeof(MyAttribute)) as MyAttribute;

            if (attribute != null)
            {

                PropertyInfo attProp = attribute.GetType().GetProperty("Name");

                var propertyValue = entityProp.GetValue(entity, null);
                var atributeNameValue = attProp.GetValue(entity, null);

                TestContext.WriteLine(string.Format("property name:{0} property value: {1} : atribute name value: {2}\n",
                    entityProp.Name, propertyValue, atributeNameValue));
            }
        }



    }
</code>

EDITED: I delete original post and added very simple clear sample. Sorry

Возможный дубликатChange Attribute's parameter at runtime Toastrackenigma
Примечание: почему ваш второй метод ловит, а затем выдает Exception? David Nelson

Ваш Ответ

2   ответа
11

аданные сборки. Ваш метод изменяет внутреннее состояние конкретного экземпляра; но когда вы снова загружаете атрибут, вы получаете другой экземпляр.

Error: User Rate Limit Exceeded Mike
Error: User Rate Limit Exceededstackoverflow.com/questions/51269/…
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededappearsError: User Rate Limit Exceeded
4

поскольку (как уже отмечалось) метаданные являются фиксированными. Однако это частично возможно с TypeDescriptor, который позволяет добавлять и заменять атрибуты во время выполнения и предоставлять полные альтернативные модели (TypeDescriptionProvider и т. Д.). Этот подход не будет соблюдаться любым кодом, использующим отражение, но любой код, использующий TypeDescriptor (чаще всего, привязка данных и другой код пользовательского интерфейса), заметит изменения.

Примечание. TypeDescriptor действительно работает только с одним типом атрибута для каждого типа / члена; атрибуты нескольких экземпляров не очень хорошо поддерживаются.

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