微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在C#中有效地使用反射

我正在C#中编写一个库,以后我将会使用一个应用程序,我希望这个库能够尽可能的高效(即不要过多地复杂一些事情,使它更有效率).但是,我有这个问题,关于如何最有效地使用反思在一个类/方法,并说明我已经简化了我的课程这个问题:
class MyClass
{
    private static Dictionary<string,object> methods;

    public void Method1()
    {
        // Do something.
    }

    public void Method2()
    {
        // Do something else.
    }
}

现在,我想要的是从类(一个私有方法尚未被创建),取一个包含method-name的字符串,然后点击该方法,简单的.这样做最简单的方法就是查看名称,获取一个名称方法,然后执行它,但这迫使我多次使用反射.这种私有方法可能被称为数千或数万次,而且需要快速.所以我想出了两个可能的解决方案.你可能会看到我添加一个包含string->对象的静态字典(用实际类型替换对象,只是写了对象,因为这两个我的例子).然后我会添加一个静态构造函数,通过该类,并将所有的methodinfos添加方法字典中.然后提出一个问题,在创建一个类的新实例时,我应该为方法创建绑定的代理,并将它们放在非静态私有dict中,或者我应该简单地使用方法字典中的MethodInfo来激发方法

平均用例将创建10个此类的实例,并且有1000个调用方法,该方法应该触发方法1或方法2,具体取决于它的字符串参数(而不是,switch-case不是一个选项,因为可扩展性如上所述,这是一个简化版本).实现这一目标最有效的方法是什么?

解决方法

显然没有人可以在没有实际尝试的情况下回答这个问题,并进行性能测试,看看你的目标是否得到满足.

反思在现代版本的框架中比以前更快,但它仍然不如简单地调用代理那么快.

我的建议是从您提出的解决方案开始:构建方法信息的缓存一次:

class MyClass
{
    static Dictionary<string,MethodInfo> cache = new ...
    public void InvokeByName(string name)
    {
        MethodInfo methodInfo = getmethodInfoFromCache(name);
        methodInfo.Invoke(this,new object[] {});
    }

当被要求调用由特定实例上的字符串标识的方法作为接收方时,按名称查找方法信息,然后使用给定的接收方调用它.衡量其性能,看看它是否符合您的目标.如果它是,伟大的不要浪费任何更多的宝贵时间,试图使更快的速度已经够快了.

如果这还不够快,那么我会做什么:

class MyClass
{
    static Dictionary<string,Action<MyClass>> cache = new ...
    public void InvokeByName(string name)
    {
        GetActionFromCache(name).Invoke(this);            
    }

那么GetActionFromCache做什么呢?如果缓存中已经有一个动作,我们就完成了.如果没有,则通过Reflection获取MethodInfo.然后使用Expression Tree库构建一个Lambda:

var methodInfo = SomehowGetTheMethodInfo(name);
// We're going to build the lambda (MyType p)=>p.<named method here>()    
var p = Expression.Parameter(typeof(MyType),"p"));
var call = Expression.Call(p,methodInfo);
var lambda = Expression.Lambda<Action<MyType>>(call,p);
var action = lambda.Compile();

现在你有一个可以用实例调用的动作.把东西放在缓存中.

顺便提一句,这是一个令人难以置信的简化的水平,C#4中的“动态”是如何工作的.我们的问题是非常复杂的,因为我们必须处理接收者和任何类型的参数.你比较容易.

原文地址:https://www.jb51.cc/csharp/93071.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐