Как класс атрибута может ссылаться на экземпляр, который его использует? - PullRequest
2 голосов
/ 23 марта 2012

Допустим, у меня есть класс атрибута:

public class MyCustomAttribute : Attribute
{
    // do stuff
}

И я использую этот атрибут в свойствах класса:

public class MyModel : BaseModel
{
    [MyCustom]
    public string Name { get; set; }
}

Есть ли способ в коде MyCustomAttribute ссылаться на экземпляр MyModel, на котором он используется?

В конечном итоге я просто экспериментирую с AOP (используя PostSharp), чтобы создать атрибуты для отслеживания, когда модель загрязнена. Так что если BaseModel имеет свойство IsDirty, я бы хотел сделать что-то подобное с PostSharp:

public class TrackDirtyPropertyAttribute : OnMethodBoundaryAspect
{
    public override void OnSuccess(MethodExecutionArgs args)
    {
        someReferenceToTheObject.IsDirty = true;
    }
}

Я пытался передать ссылку в конструктор атрибута:

public class TrackDirtyPropertyAttribute : OnMethodBoundaryAspect
{
    private BaseModel _currentObject { get; set; }

    public TrackDirtyPropertyAttribute(BaseModel currentObject)
    {
        _currentObject = currentObject;
    }

    public override void OnSuccess(MethodExecutionArgs args)
    {
        _currentObject.IsDirty = true;
    }
}

Однако, когда я использую это:

[TrackDirtyProperty(this)]
public string Name { get; set; }

Он говорит мне, что this недоступен в этом контексте.

Ответы [ 2 ]

4 голосов
/ 23 марта 2012

Вы должны сделать это так:

public class TrackDirtyPropertyAttribute : OnMethodBoundaryAspect 
{ 
    public override void OnSuccess(MethodExecutionArgs args) 
    { 
        ((BaseModel) args.Instance).IsDirty = true; 
    } 
} 
2 голосов
/ 23 марта 2012

Ваш конструктор не будет работать (по крайней мере, с this), потому что аргументы конструктора атрибута должны быть доступны в статическом контексте. И по умолчанию вы не можете просто получить доступ к экземпляру используемого типа - что имеет смысл, поскольку это по сути метаданные (применяются к определению, а не к экземплярам - экземпляры просто «привязаны» к нему). Таким образом, вы можете напрямую обращаться к атрибутам типа, но не к экземплярам типа, используемого атрибутом.

Вероятно, вы могли бы получить это через какое-то надуманное размышление и так далее (я даже не собираюсь думать об этом), но не так элегантно, как другим.

С другой стороны, для меня не имеет смысла хранить состояние элемента в атрибуте - этого недостаточно для сохранения. Выполнение вычислений для извлечения значения (скажем, вы захватили экземпляр и вам удалось запустить некоторую логику, чтобы определить, является ли он «грязным» и предоставить значение «реального времени» в этом смысле), но использовать его для сохранения информация, примененная к нему после факта объявления , кажется бесполезной, так как в каком экземпляре атрибута он сохраняется в любом случае? В любом случае, и независимо от того, что я, возможно, полностью упустил, говоря это, для этого и нужны сами экземпляры.

...