簡體   English   中英

在運行時更改自定義屬性的參數

[英]Change custom attribute's parameter at runtime

我需要在運行時更改屬性的參數。 我將我的問題簡化為簡單的例子。

屬性 class:

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

我創建了 class MyEntity 的實例。 我可以更改對象屬性的值,但無法更改 object 實體上的屬性屬性 Name 的值。 可能嗎?

object 實體的屬性值我可以用這部分代碼更改:

                entityProp.SetValue(entity,"NewData",null);

但我不知道如何更改 object 實體上屬性的屬性名稱的值

這不起作用:

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

編輯:我刪除了原始帖子並添加了非常簡單的清晰示例。 對不起

您不能在運行時更改屬性。 它們被嵌入到程序集的元數據中。 您的方法正在更改特定實例的內部 state; 但是當你再次加載屬性時,你會得到一個不同的實例。

這對於反射是不可能的,因為(如前所述)元數據是固定的。 然而,TypeDescriptor 在一定程度上是可行的,它允許在運行時添加和替換屬性,並提供完整的替代模型(TypeDescriptionProvider 等)。 這種方法不會被任何使用反射的代碼所遵循,但任何使用 TypeDescriptor 的代碼(最典型的是數據綁定和其他 UI 代碼)都會注意到這些變化。

注意 TypeDescriptor 僅適用於每個類型/成員的每個屬性類型之一; 多實例屬性沒有得到很好的支持。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM