Как я могу установить значение свойства для атрибута объекта? - PullRequest
1 голос
/ 31 июля 2011

Я пытаюсь установить значение свойства для атрибута класса.

[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 ]

2 голосов
/ 31 июля 2011

Я понятия не имею, возможно ли это вообще, но не так, как предполагается использовать атрибуты.Я не знаю, есть ли какие-либо гарантии относительно того, как и когда создаются экземпляры атрибутов.Например, вполне возможно, что каждый раз, когда вы запрашиваете тип или член для его атрибутов, они снова десериализуются из метаданных.

В основном я думаю, что вам следует рассматривать атрибуты являются неизменными после компиляции, даже если они имеют свойства с установщиками.

РЕДАКТИРОВАТЬ: Эта короткая, но полная программа, кажется, указывает, что 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
    }
}
0 голосов
/ 31 июля 2011

Единственный способ сделать это во время выполнения - это моделировать атрибуты во время выполнения, а не отражения. К счастью TypeDescriptor делает это уже. Таким образом, вы должны обнаружить, что если вы используете только TypeDescriptor для получения атрибута, то TypeDescriptor.AddAttributes(...) должен выполнить работу по назначению нового атрибута во время выполнения;

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

Однако это работает, только если код, использующий атрибут, использует TypeDescriptor.GetAttributes(...).

...