假设我有一个属性类:
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 :(得分:4)
你应该这样做:
public class TrackDirtyPropertyAttribute : OnMethodBoundaryAspect
{
public override void OnSuccess(MethodExecutionArgs args)
{
((BaseModel) args.Instance).IsDirty = true;
}
}
答案 1 :(得分:2)
您的构造函数将无法工作(至少不能使用this
),因为属性构造函数参数必须可以在静态上下文中访问。并且默认情况下,您不能简单地访问利用类型的实例 - 这是有道理的,因为这实际上是元数据(应用于定义,而不是实例 - 实例刚刚与它绑在一起)。因此,您可以本机访问类型的属性,但不能访问属性使用的类型的实例。
你可能会通过一些人为的反思等等(我甚至不打算冒险思考这个问题),但是,并不像其他方式那样优雅。
另一方面,对于我来说,将属性的状态存储在属性中是没有意义的 - 这不够持久。进行计算以检索一个值(比如你确实得到了一个实例,并设法运行一些逻辑来确定它是否“脏”并在这个意义上提供'实时'值)是的,但使用它来保持在声明之后应用于它的信息似乎是徒劳的,因为该属性的哪个实例仍然存在?在任何情况下,无论我在说这个时可能完全错过了什么,这就是实例本身的用途。