






















如果想创建一个包含在一个未加载程序集中的类,一般可以使用两种方法:
(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, false, out 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(this, true);
}
MethodBase base1 = binder.BindToMethod(bindingAttr, baseArray1, ref args, null, culture, null, out 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要高的。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。