如何在对象的属性上设置属性的值?

时间:2011-07-31 17:44:10

标签: c# reflection custom-attributes

我正在尝试在类的属性上设置属性的值。

[FooAttr(ThePropertyIWantToSet=null)]
public class Foo
{
}

Foo theFoo = new Foo();
theFoo.SetAttributeProperty<FooAttrAttribute>("ThePropertyIWantToSet", theValueIWantToSet);

这是我编写的SetAttributeProperty扩展方法。它编译并运行但似乎没有设置属性。

public static void SetAttributeProperty<T>(this object instance, string fieldName, object value) where T : Attribute
{
    var attr = instance.GetType().GetCustomAttributes(typeof (T), false).FirstOrDefault();

    PropertyInfo pi = attr.GetType().GetProperty(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty);
    pi.SetValue(attr, value, null);
}

我可能缺少什么想法?

2 个答案:

答案 0 :(得分:2)

我不知道这是否可能,但不是如何使用属性。我不知道有关如何以及何时创建属性实例的任何保证。例如,每次询问类型或成员的属性时,很可能会再次从元数据中反序列化它们。

基本上我认为你应该在编译后将属性视为不可变的,即使它们具有带有setter的属性。

编辑:这个简短但完整的程序似乎表明每次调用Type.GetCustomAttributes确实可以创建一个新实例:

using System;
using System.Runtime.CompilerServices;

[AttributeUsageAttribute(AttributeTargets.All)]
class FooAttribute : Attribute
{
}

[Foo]
class Bar
{
}

class Program
{
    static void Main(string[] args)
    {
        var attr = typeof(Bar).GetCustomAttributes(typeof(FooAttribute), true)[0];
        var attr2 = typeof(Bar).GetCustomAttributes(typeof(FooAttribute), true)[0];
        Console.WriteLine(attr == attr2); // Prints False
    }
}

答案 1 :(得分:0)

在运行时执行此操作的唯一方法是在运行时而不是反射中对属性建模。幸运的是TypeDescriptor已经这样做了。所以你应该发现,如果你只使用TypeDescriptor来获取属性,那么TypeDescriptor.AddAttributes(...)应该在运行时分配一个新属性;

TypeDescriptor.AddAttributes(typeof(TargetType),
    new Attribute[] {yourAttribWithNewValue});

但是,这仅在使用该属性的代码使用TypeDescriptor.GetAttributes(...)时才有效。