首页 > 其他分享 >提高反射的效率

提高反射的效率

时间:2024-03-15 17:44:19浏览次数:21  
标签:反射 提高 public class typeof MethodInfo methodInfo Type 效率

使用委托调用比直接调用慢10%,使用反射是直接调用的600倍,当然这取决于方法内部是否还外拉数据,但是反射转委托调用的好处显而易见
所以我们需要使用反射和泛型方法来动态创建委托,并通过这些委托来调用特定的方法
先创建一个带有返回值的

public class RegisterDemo
{
    private static RegisterManager _registerManager ;
    public static void GetRegister()
    {
        MethodInfo methodInfo = typeof(RegisterManager).GetMethod("RegiserScoped", new Type[] { typeof(Type), typeof(Type) });
        Func<RegisterManager, object, object, object> Register = MagicMethod<RegisterManager>(methodInfo);

        Register(_registerManager, typeof(A), typeof(B));
    }

    static Func<T, object, object, object> MagicMethod<T>(MethodInfo methodInfo) where T : class
    {
        MethodInfo genericHelper = typeof(RegisterDemo).GetMethod("MagicMethodHelper", BindingFlags.Static | BindingFlags.NonPublic);
        MethodInfo constructHelper = genericHelper.MakeGenericMethod(typeof(T), methodInfo.GetParameters()[0].ParameterType, methodInfo.GetParameters()[1].ParameterType,methodInfo.ReturnType);
        
        object ret = constructHelper.Invoke(null, new object[] { methodInfo });
        return (Func<T, object, object, object>)ret;
    }

    static Func<TTarget, object, object, object> MagicMethodHelper<TTarget, TParam1, TParam2, TReturn>(MethodInfo method)
        where TTarget : class, new()
    {
        // 将方法转为委托
        Func<TTarget, TParam1, TParam2, TReturn> func = (Func<TTarget, TParam1, TParam2, TReturn>)Delegate.CreateDelegate
            (typeof(Func<TTarget, TParam1, TParam2, TReturn>), method);

        // 创建一个更弱的委托调用上面的委托
        Func<TTarget, object, object, object> ret = (TTarget target, object param1, object param2) => func(target, (TParam1)param1, (TParam2)param2);
        return ret;
    }
}
public class RegisterManager
{
    public string RegiserScoped(Type from,Type to) 
    {
        Console.WriteLine(123);
        return "1111";
    }
}
public class A
{

}
public class B { }

我们需要理解委托的参数含义,一个目标值,两个参数,一个返回值,注意看我们的RegiserScoped方法
它的返回值是string,目标值是RegisterManager,参数是两个Type,那么我们的委托需要签名,
在MagicMethodHelper方法中返回值是Func<TTarget, object, object, object>
其中TTarget指的是RegisterManager,后面三个object分别指的是两个参数Type,和返回值string
同理,我们写void类型的时候不需要返回值,这个时候用Action

public class RegisterDemo2
{
    private static RegisterManager2 _registerManager;
    public static void GetRegister()
    {
        MethodInfo methodInfo = typeof(RegisterManager2).GetMethod("RegiserScoped", new Type[] { typeof(Type), typeof(Type) });
        Action<RegisterManager2, object, object> Register = MagicMethod<RegisterManager2>(methodInfo);

        Register(_registerManager, typeof(A2), typeof(B2));
    }
    static Action<T, object, object> MagicMethod<T>(MethodInfo methodInfo) where T : class
    {
        MethodInfo genericHelper = typeof(RegisterDemo2).GetMethod("MagicMethodHelper", BindingFlags.Static | BindingFlags.NonPublic);
        MethodInfo constructHelper = genericHelper.MakeGenericMethod(typeof(T), methodInfo.GetParameters()[0].ParameterType, methodInfo.GetParameters()[1].ParameterType);

        object ret = constructHelper.Invoke(null, new object[] { methodInfo });
        return (Action<T, object, object>)ret;
    }

    static Action<TTarget, object, object> MagicMethodHelper<TTarget, TParam1, TParam2>(MethodInfo method)
        where TTarget : class, new()
    {
        // 将方法转为委托
        Action<TTarget, TParam1, TParam2> action = (Action<TTarget, TParam1, TParam2>)Delegate.CreateDelegate
            (typeof(Action<TTarget, TParam1, TParam2>), method);

        // 创建一个更弱的委托调用上面的委托
        Action<TTarget, object, object> ret = (TTarget target, object param1, object param2) => action(target, (TParam1)param1, (TParam2)param2);
        return ret;
    }
}

public class RegisterManager2
{
    public void RegiserScoped(Type from, Type to)
    {
        Console.WriteLine(123);
    }
}

public class A2
{

}

public class B2
{

}

在RegisterManager2中的RegiserScoped方法没有返回值,所以我们的委托需要用到Action,同上
原文来自

https://codeblog.jonskeet.uk/2008/08/09/making-reflection-fly-and-exploring-delegates/

标签:反射,提高,public,class,typeof,MethodInfo,methodInfo,Type,效率
From: https://www.cnblogs.com/guchen33/p/18075928

相关文章

  • 效率工具整理
    前言每次使用新设备,最最最讨厌的就是配环境,程序员懂得都懂,特别是笔者这种有强迫症的,一定要都配好了才能开始工作,痛定思痛,写一个一键配置的脚本,方便平常环境迁移。该脚本主要包含了日常工作使用的cli工具和各语言环境,每个都写好了安装指令,都是笔者常用的配置,直接运行也可以,会跳过......
  • 8分SCI | 揭示随机森林的解释奥秘:探讨LIME技术如何提高模型的可解释性与可信度!
    一、引言LocalInterpretableModel-agnosticExplanations(LIME)技术作为一种局部可解释性方法,能够解释机器学习模型的预测结果,并提供针对单个样本的解释。通过生成局部线性模型来近似原始模型的预测,LIME技术可以帮助用户理解模型在特定样本上的决策过程,提高模型的可解......
  • 什么是服务器端广告插入(server side ad insertion - SSAI)- 为什么说采用IAB技术实验室
    服务器端广告插入(SSAI-serversideadinsertion)是在联网(有线)电视上广告竞标行动中的最流行的技术解决方案之一。SSAI是一种在视频流加载到用户设备之前将广告植入在一起的技术。它可以用于任何连接或超顶级(overthetop-OTT)视频环境,包括社交环境,但大部分需求来自CTV的爆......
  • YOLOv9改进策略:注意力机制 |通道注意力和空间注意力CBAM | GAM超越CBAM,不计成本提高精
    ......
  • go反射实战
    文章目录demo1数据类型判断demo2打印任意类型数据demo1数据类型判断使用reflect.TypeOf()方法打印go中数据类型,可参考go官方API文档;使用格式化参数%T也能打印数据类型。packagemainimport"fmt"import"reflect"import"io"import"os"funcmain(){ T......
  • 提高级字符串
    哈希和哈希表前缀函数&&KMP前缀函数定义:\(nxt[i]\)KMP例题1.无线传输(luogu4391/ybt1467)求一个字符串的最短周期结论:\[ans=n-nxt[n]\]证明:两条白线是最长的相等的前缀和后缀可得\(1=2,2=3,3=4,4=5......\)所以周期的长度就是1的长度也就是\(n-nxt[n]\)2.powers......
  • 面试官:说说反射的底层实现原理?
    反射是Java面试中必问的面试题,但只有很少人能真正的理解“反射”并讲明白反射,更别说能说清楚它的底层实现原理了。所以本文就通过大白话的方式来系统的讲解一下反射,希望大家看完之后能真正的理解并掌握“反射”这项技术。1.什么是反射?反射在程序运行期间动态获取类和操纵类的......
  • Java反射和注解基本用法
    Java注解和反射Java注解什么是注解Annotation是从JDK5.0开始引入的新技术Annotation作用:不是程序本身,可以对程序做出解释可以被其他程序(比如编译器)读取Annotation格式:注解是以@注解名在代码中存在的,还可以添加一些参数值,例如:@Service(value="")Annotation在哪......
  • 【专业揭秘】一键搞定自动点赞关注,提升社交效率的神器来了!
    在数字时代,社交媒体已经成为我们生活的一部分。随之而来的自动化工具也不断涌现,其中自动点赞、自动关注和自动评论工具受到了广泛关注。这类工具通常通过模拟人类用户的行为来增加账户的互动性和可见度。这些自动化工具的工作机制并不复杂。它们通过预设的脚本或算法,自动执行......
  • 开启线程处理数据,提高响应速度
    //此线程类必须实现Runnable接口publicclassXmzNoticeErrorThreadimplementsRunnable{privateICertImportErrorRecServiceiErrorRecService=ContainerFactory.getContainInfo().getComponent(ICertImportErrorRecService.class);privatei......