C# C语言中使用反射的方法拦截#

C# C语言中使用反射的方法拦截#,c#,reflection,C#,Reflection,我编写了一个抽象类,它使用反射来查找构造函数中标记有属性的字段,如下所示: [AttributeUsage(AttributeTargets.Field)] public class TrackedField : Attribute {} public class ATrackedObject { public ATrackedObject() { Type objType = this.GetType(); foreach(FieldInfo f in

我编写了一个抽象类,它使用反射来查找构造函数中标记有属性的字段,如下所示:

[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
            }
        }
    }
}
我想做的是:

  • 创建另一个属性TrackedMethod
  • 在构造函数中,在 与TrackedFields的方式相同,查找标记为的所有方法 跟踪法
  • 更改该方法,以便在调用它时 首先调用ATrackedObject内的方法,或者 完全替换该方法或向其中注入代码,但是 在不破坏能力的情况下,至少可以看到原作是什么 方法调用为,包括参数
  • 没有第三方库,应该与.NET3.5兼容
  • 我已经看到许多SE线程在讨论如何做到这一点,并且所有的答案都依赖于能够使用第三方库——然而,没有一个问题似乎与我的用例完全匹配——我可以100%地确保需要跟踪方法的每个对象都将从进行跟踪的类继承

    我不知道这是否可能,但我想知道,既然存在像PostSharp和其他类似的IoC/AOP库,它们肯定是通过某种机制运行的——我假设反射。发射起了作用——但是什么,以及如何

    以下是一些类似的问题,在我看来,这些问题并不能回答我的特定场景,或者依赖于第三方库:

    (这很有帮助,但缺少了如何实际注入代码的关键部分。)


    有没有办法使这项技术(属性->基类构造函数->反射->方法拦截)可行?

    这样的方法能满足您的需要吗

    [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");
    }
    
    这是通过一个简单的
    操作
    属性完成的,但可以扩展为使用
    Func

    编辑:忘记包含用法和输出

    用法:

    static void Main(string[] args)
    {
        var obj = new ATrackedObject();
        obj.SomeMethod();
    
        Console.Read();
    }
    
    输出:

    Tracking SomeMethod
    Some Method Called
    

    “没有第三方库”——那么你的问题太宽泛了。有几种工具可以做这类事情(请参阅“面向方面编程”,PostSharp等)。但是如果你排除了这些,那么就没有了……语言不包括这一点,你基本上可以自己编写整个功能。你可以这样做(很明显,因为其他人有),但解释如何做到这一点远远超出了一个好的、有用的堆栈溢出问题的范围。告诉我为什么在2017年年底,你被限制在.NET 3.5上?使用反射截取方法就像读报纸,希望它能重写文章。哇,太快了!如果你知道如何使它与Func一起工作,那将非常有帮助pful.现在,如果动作有参数,比如动作或动作,我就很难让它与动作一起工作。不过,基本操作确实有效,我至少可以用它做一些我想做的事情,尽管用参数解决Func或动作会很理想!当然,我可以更新答案,但功能是什么您希望注入到这些方法中吗?很可能有一个比这个更好的解决方案,尽管这将“起作用”,每个方法可能有不同的参数和返回类型,尽管如果无法使用,我可以只处理“对象”进进出出。我正在编写一个实用程序来帮助减少一个网络项目的样板代码,不过说实话,我的固执是希望它也能正常工作的一个主要因素。这个想法是在调用某些方法调用其他方法时截取它们——在这种情况下,计划是在属性中包含几个字段来调用其他方法确定要采取的行动,包括在网络对等点上记录和触发RPC,但也可能以其他方式使用。这可能是一种“全神贯注于你是否可以,你没有停下来思考你是否应该”的情况,但我真的很好奇这一点。