惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

W
WeLiveSecurity
T
Tenable Blog
Project Zero
Project Zero
C
Cybersecurity and Infrastructure Security Agency CISA
T
The Exploit Database - CXSecurity.com
P
Palo Alto Networks Blog
S
Schneier on Security
Scott Helme
Scott Helme
S
Securelist
Know Your Adversary
Know Your Adversary
Vercel News
Vercel News
IT之家
IT之家
V
V2EX
F
Fortinet All Blogs
Simon Willison's Weblog
Simon Willison's Weblog
K
Kaspersky official blog
博客园_首页
T
Tailwind CSS Blog
The GitHub Blog
The GitHub Blog
Spread Privacy
Spread Privacy
Microsoft Security Blog
Microsoft Security Blog
Cisco Talos Blog
Cisco Talos Blog
The Register - Security
The Register - Security
有赞技术团队
有赞技术团队
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Cyberwarzone
Cyberwarzone
Google DeepMind News
Google DeepMind News
The Hacker News
The Hacker News
L
LINUX DO - 热门话题
Hugging Face - Blog
Hugging Face - Blog
博客园 - 三生石上(FineUI控件)
A
Arctic Wolf
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
C
CXSECURITY Database RSS Feed - CXSecurity.com
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
T
Threat Research - Cisco Blogs
P
Proofpoint News Feed
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
P
Privacy & Cybersecurity Law Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
C
CERT Recently Published Vulnerability Notes
S
SegmentFault 最新的问题
AWS News Blog
AWS News Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
罗磊的独立博客
Apple Machine Learning Research
Apple Machine Learning Research
P
Proofpoint News Feed
The Cloudflare Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
Vulnerabilities – Threatpost

博客园 - Kevin Li

使用WMI远程部署/更新BizTalk程序集 基于WS-AtomicTransaction标准的WCF远程分布式事务(补充) 基于WS-AtomicTransaction标准的WCF远程分布式事务(二) 基于WS-AtomicTransaction标准的WCF远程分布式事务(一) 在Jeffrey Zhao的基础上+反编译System.Web.Extensions.Design得到的完整Ajax代码 .net remoting的事务传播以及wcf分布式事务 在多线程环境下使用HttpWebRequest或者调用Web Service 一篇介绍.NET 2.0 范型挺全面的文章 C# 2.0中的范型和Nullable范型 Windows 2003 下分布式事务协调器(DTC)的配置 使用SQLSourceSafe控制数据库的版本 MySql 主键(自动增加)的数据类型所带来的错误 使用TraceListener 自动保存跟踪信息到文件中 接口属性集成与智能提示的奇怪问题 动态创建程序集中的类 使用NUnit测试包含应用程序配置的dll文件 解决“COM+ 无法与 Microsoft 分布式事务协调程序交谈”的问题 [导入]一些很有用的Reflector 插件 Web安全性原则
动态创建程序集中的类
Kevin Li · 2004-12-04 · via 博客园 - Kevin Li

如果想创建一个包含在一个未加载程序集中的类,一般可以使用两种方法:
(1)使用System.Activator.CreateInstance()方法;

(2)使用反射获取类的构造函数的签名信息,并使用Invoke方法调用。

以下简单的举了两个例子说明这两种方法的用法:

其中:NothinButAspNet.SqlMembershipProvider表示要创建的类的名字(包括命名控件),SqlMembershipProvider是该类所在的程序集。

那么两种方法在效果和性能有没有具体的区别呢?
1、应该说两种方法在效果上是没有区别的。
2、在性能上,两者应该也没有本质的区别,这一点只要我们通过反编译System.Activator这个类就可以看到:

object CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, object[] args, CultureInfo culture, object[] activationAttributes)
{
      
object obj1 = null;
      
try
      
{
            
try
            
{
                  
bool flag1;
                  
object obj2;
                  
if (activationAttributes != null)
                  
{
                        ActivationServices.PushActivationAttributes(
this, activationAttributes);
                  }

                  
if (args == null)
                  
{
                        args 
= new object[0];
                  }

                  
int num1 = args.Length;
                  
if (binder == null)
                  
{
                        binder 
= Type.DefaultBinder;
                  }

                  
if ((((num1 == 0&& ((bindingAttr & BindingFlags.Public) != BindingFlags.Default)) && ((bindingAttr & BindingFlags.Instance) != BindingFlags.Default)) && (this.IsGenericCOMObjectImpl() || this.IsSubclassOf(RuntimeType.valueType)))
                  
{
                        
return this.CreateInstanceImpl(((bindingAttr & BindingFlags.NonPublic) == BindingFlags.Default) && true);
                  }

                  MethodBase[] baseArray1 
= this.GetMemberCons(bindingAttr, CallingConventions.Any, null, num1, falseout flag1);
                  
if (baseArray1 == null)
                  
{
                        
if (activationAttributes != null)
                        
{
                              ActivationServices.PopActivationAttributes(
this);
                              activationAttributes 
= null;
                        }

                        
throw new MissingMethodException(string.Format(Environment.GetResourceString("MissingConstructor_Name"), this.FullName));
                  }

                  
if (((num1 == 0&& (baseArray1.Length == 1)) && ((bindingAttr & BindingFlags.OptionalParamBinding) == BindingFlags.Default))
                  
{
                        
return Activator.CreateInstance(thistrue);
                  }

                  MethodBase base1 
= binder.BindToMethod(bindingAttr, baseArray1, ref args, null, culture, nullout obj2);
                  
if (base1 == null)
                  
{
                        
if (activationAttributes != null)
                        
{
                              ActivationServices.PopActivationAttributes(
this);
                              activationAttributes 
= null;
                        }

                        
throw new MissingMethodException(string.Format(Environment.GetResourceString("MissingConstructor_Name"), this.FullName));
                  }

                  
if (flag1)
                  
{
                        
new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
                  }

                  obj1 
= ((ConstructorInfo) base1).Invoke(bindingAttr, binder, args, culture);
                  
if (obj2 != null)
                  
{
                        binder.ReorderArgumentArray(
ref args, obj2);
                  }

                  
return obj1;
            }

            
finally
            
{
                  
if (activationAttributes != null)
                  
{
                        ActivationServices.PopActivationAttributes(
this);
                  }

            }

      }

      
catch (Exception)
      
{
            
throw;
      }

      
return obj1;
}

实际上Activator也是通过反射来实现的,所以两者应该没有明显的性能区别。

但是在查看微软提高的Provider Pattern的例子中却发现,他们使用的是第一种方法,为什么呢?
实际上通过下面的代码可以看到,虽然同样通过反射,但是使用我们却可以先把通过反射获取得到的构造函数信息缓存起来,下次直接调用Invoke方法,这样性能应该是要比直接使用Activator.CreateInstance要高的。