在运行时更改自定义属性的参数

Mik*_*ike 12 c# reflection runtime custom-attributes

我需要在运行时更改属性的参数.我将我的问题简化为简单的例子.

属性类:

    [AttributeUsage(AttributeTargets.Property)]
    public class MyAttribute : Attribute
    {
        public string Name { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

简单实体,它使用属性修饰属性:

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

        [MyAttribute(Name = "OldValue2")]
        public string Data2 { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

我创建了MyEntity类的实例.我可以更改对象属性的值,但是我不能在对象实体上更改属性的属性Name的值.可能吗?

对象实体的属性值我可以用这部分代码改变:

                entityProp.SetValue(entity,"NewData",null);
Run Code Online (Sandbox Code Playgroud)

但我不知道如何更改对象实体上属性Name的值

这不起作用:

attProp.SetValue(attribute,"NewData",null);
Run Code Online (Sandbox Code Playgroud)

属性的价值名称仍然是原创的.

这是所有测试代码.谢谢你的帮助.

    [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));
            }
        }



    }
Run Code Online (Sandbox Code Playgroud)

编辑:我删除原始帖子,并添加了非常简单的明确样本.抱歉

Dav*_*son 12

您无法在运行时更改属性.它们嵌入到程序集的元数据中.您的方法是更改​​特定实例的内部状态; 但是当您再次加载该属性时,您将获得一个不同的实例.


Mar*_*ell 5

这在反射中是不可能的,因为(如前所述)元数据是固定的。但是,TypeDescriptor 部分可能,它允许在运行时添加和替换属性,并提供完整的替代模型(TypeDescriptionProvider 等)。任何使用反射的代码都不会遵守这种方法,但任何使用 TypeDescriptor 的代码(最常见的是数据绑定和其他 UI 代码)都会注意到这些变化。

注意 TypeDescriptor 只真正适用于每个类型/成员的每个属性类型之一;多实例属性没有得到很好的支持。