我写了一个抽象类,它使用反射来查找构造函数中标有Attribute的字段,如下所示:
[AttributeUsage(AttributeTargets.Field)]
public class TrackedField : Attribute {}
public class ATrackedObject {
public ATrackedObject() {
Type objType = this.GetType();
foreach(FieldInfo f in objType.GetFields()) {
if(f.IsDefined(typeof(TrackedField)), false)) {
//Add field to list to keep tabs on periodically
}
}
}
}
我想做的是:
我已经看过许多SE线程讨论如何做到这一点,并且所有的答案都依赖于能够使用第三方库 - 但是,没有一个问题似乎与我的用例完全一致 - 我可以确保100%需要跟踪方法的每个对象都将从执行跟踪的类继承。
我不确定这是可能的,但我想知道,因为像PostSharp等IoC / AOP库存在,肯定它们必须通过某种机制运行 - 我认为Reflection.Emit扮演一个角色 - 什么,怎么样?
以下是一些类似的问题,这些问题在我看来并不是我特定场景的答案,或者依赖于第三方库:
custom-attribute-to-process-info-before-a-method-is-called
how-do-i-intercept-a-method-call-in-c(这很有帮助,但遗漏了如何实际注入代码的重要组成部分
有没有办法使这种技术(属性 - >基类构造函数 - >反射 - >方法拦截)可行?
答案 0 :(得分:2)
这样的事情可以满足您的需求吗?
[AttributeUsage(AttributeTargets.Field)]
public class TrackedField : Attribute { }
public class ATrackedObject
{
public ATrackedObject()
{
Type objType = this.GetType();
foreach (FieldInfo f in objType.GetFields())
{
if (f.IsDefined(typeof(TrackedField), false)) {
if (f.FieldType == typeof(Action))
{
var currentValue = f.GetValue(this) as Action;
Action newValue = () =>
{
Console.WriteLine($"Tracking {f.Name}");
currentValue.Invoke();
};
f.SetValue(this, newValue);
}
}
}
}
[TrackedField]
public Action SomeMethod = () => Console.WriteLine("Some Method Called");
}
这是通过简单的Action
属性完成的,但可以扩展为使用Func<>
编辑:忘记包含用法和输出。
用法:
static void Main(string[] args)
{
var obj = new ATrackedObject();
obj.SomeMethod();
Console.Read();
}
输出:
Tracking SomeMethod
Some Method Called