【问题标题】:How Can an Attribute Class Reference the Instance that Uses It?属性类如何引用使用它的实例?
【发布时间】:2012-03-23 14:54:53
【问题描述】:

假设我有一个属性类:

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 在该上下文中不可用。

【问题讨论】:

  • 在编织发生的时候,会有 0 个类的instances - 你的属性与一个类相关联,not有一个类的实例。
  • 如果使用 PostSharp,那么您将按照@Gael Fraiteur 的建议进行操作。

标签: c# aop custom-attributes postsharp


【解决方案1】:

你应该这样做:

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

【讨论】:

    【解决方案2】:

    您的构造函数将不起作用(至少不适用于this),因为属性构造函数参数必须在静态上下文中可访问。默认情况下,您不能简单地访问使用类型的实例 - 这是有道理的,因为这本质上是元数据(应用于定义,而不是实例 - 实例只是“捆绑”它)。因此,您可以本机访问类型的属性,但不能访问属性使用的类型的实例。

    您可能可以通过一些人为的反思等等来获得它(我什至不会冒险考虑这个),但是,一种方式不如另一种方式那么优雅。

    另一方面,在属性中存储元素的 状态 对我来说意义不大——这还不够持久。进行计算以检索值(假设您确实获得了实例,并设法运行一些逻辑来确定它是否“脏”并在这个意义上提供“实时”值)是的,但是使用它来持久化在声明之后应用到它的信息似乎是徒劳的,因为它要保留在哪个属性实例中?无论如何,不​​管我在说这句话时可能完全错过了什么,这就是实例本身的用途。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-06-07
      • 1970-01-01
      • 1970-01-01
      • 2020-07-26
      • 1970-01-01
      • 2020-04-23
      • 1970-01-01
      相关资源
      最近更新 更多