我需要在运行时更改属性的参数。我将我的问题简化为简单的例子。
属性类:
[AttributeUsage(AttributeTargets.Property)]
public class MyAttribute : Attribute
{
public string Name { get; set; }
}
具有属性的简单实体:
public class MyEntity
{
[MyAttribute(Name="OldValue1")]
public string Data1{ get; set; }
[MyAttribute(Name = "OldValue2")]
public string Data2 { get; set; }
}
我创建了MyEntity类的实例。我可以更改对象属性的值,但是我不能在对象实体上更改属性的属性Name的值。有可能吗?
对象实体的属性值我可以用这部分代码改变:
entityProp.SetValue(entity,"NewData",null);
但我不知道如何更改对象实体
上属性的属性Name的值这不起作用:
attProp.SetValue(attribute,"NewData",null);
属性的价值名称仍然是原创的。
这是所有测试代码。谢谢你的帮助。
[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));
}
}
}
已编辑:我删除了原帖并添加了非常简单明了的样本。遗憾
答案 0 :(得分:11)
您无法在运行时更改属性。它们嵌入到程序集的元数据中。您的方法是更改特定实例的内部状态;但是当你再次加载属性时,你会得到一个不同的实例。
答案 1 :(得分:4)
这是不可能的反射,因为(如前所述)元数据是固定的。但是,部分可能使用TypeDescriptor,它允许在运行时添加和替换属性,并提供完整的替代模型(TypeDescriptionProvider等)。任何使用反射的代码都不会遵循此方法,但使用TypeDescriptor的任何代码(最常见的是数据绑定和其他UI代码)都会注意到这些更改。
注意TypeDescriptor仅适用于每个typ / member的每个属性类型之一;多实例属性不受支持。