扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
String className = "MyNamesapce.MyClass";
ConstructorInfo ci = Type.GetType(className).GetConstructor(new Type[0]);
Object o1 = ci.Invoke();
Object o2 = Activator.CreateInstance(Type.GetType(className);
var className = “MyClass”;
var myObj = eval(“new “ + className);
public abstract class Creator
...{
public abstract Object CreateObject(Object[] param);
private staticvoid CreateMethod(TypeBuilder tb, Type originalType, Object[] param);
public static Object New(Type type, params Object[] param)
}
AssemblyBuilder dynamicAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Run);
ModuleBuilder moduleBuilder = dynamicAssembly.DefineDynamicModule("MainModule");
TypeBuilder tb = moduleBuilder.DefineType("__dynamicCreator." + type.FullName, TypeAttributes.Public | TypeAttributes.Class, typeof(Creator));
CreateMethod(tb, type, param);
Creator creator = (Creator)Activator.CreateInstance(tb.CreateType());
return creator.CreateObject(param);
MethodInfo mi = typeof(Creator).GetMethod("CreateObject");
MethodBuilder mb = tb.DefineMethod("CreateObject", mi.Attributes & ~MethodAttributes.Abstract, mi.CallingConvention, mi.ReturnType, new Type[] ...{ typeof(Object[]) });
ConstructorInfo[] cis = originalType.GetConstructors(); //反射出所有的构造函数
ConstructorInfo theCi = null;
ParameterInfo[] cpis = null;
foreach(ConstructorInfo ci in cis)
...{
cpis = ci.GetParameters();
if (cpis.Length != param.Length) //参数个数不相符
continue;
theCi = ci;
for (int i = 0; i < cpis.Length; i++)
...{
if (!(param[i] == null || param[i].GetType() == cpis[i].ParameterType || param[i].GetType().IsSubclassOf(cpis[i].ParameterType))) //参数类型不相符
...{
theCi = null;
break;
}
}
if (theCi != null) //如果找到了完全相符的构造函数
break;
}
if (theCi == null)
throw new ArgumentException("错误的参数个数或类型");
ILGenerator ilg = mb.GetILGenerator();
for (int i = 0; i < param.Length; i++)
...{这里要循环处理传入的每一个参数,以下通过IL来完成取数组元素并压栈的操作:
ilg.Emit(OpCodes.Ldarg_1); //把参数数组放入栈
ilg.Emit(OpCodes.Ldc_I4, i); //把下标压入栈
ilg.Emit(OpCodes.Ldelem_Ref); //以引用的方法从数组中取出需要的内容并放入栈
if (cpis[i].ParameterType.IsValueType) //判断是否需要拆箱
ilg.Emit(OpCodes.Unbox_Any, cpis[i].ParameterType); //拆箱为需要的类型
}
ilg.Emit(OpCodes.Newobj, theCi);
ilg.Emit(OpCodes.Ret);
tb.DefineMethodOverride(mb, mi); // 定义方法重载
public class MyClass
...{
public MyClass(int p1, string p2) ...{ }
}
String className = "MyClass";
Type t = Type.GetType(className);
Object o = Creator.New(t, 1, "haha");
public class A
...{
public A(string s, string s2, string s3, string s4, string s5, string s6, string s7, string s8, string s9) ...{ }
public A(string s, string s2, string s3) ...{ }
public A(string s) ...{ }
public A(int a, int b, int c, int d, int e, int f, int g, int h, int i) ...{ }
public A(int a, int b, int c) ...{ }
public A(int a) ...{ }
}|
调用方式 |
Activator.
CreateInstance |
ConstructorInfo.
Invoke |
Creator.New |
直接使用new | |
|
引用类型 |
1个参数 |
59281.25 |
18843.75 |
2296.875 |
140.625 |
|
3个参数 |
72031.25 |
24000 |
2453.125 |
171.875 | |
|
9个参数 |
102843.75 |
39218.75 |
3187.5 |
156.25 | |
|
值类型 |
1个参数 |
60468.75 |
19921.875 |
2375 |
109.375 |
|
3个参数 |
73953.125 |
26390.625 |
2796.875 |
109.375 | |
|
9个参数 |
110656.25 |
46765.625 |
4453.125 |
109.375 | |
可见,直接使用new还是最快的,动态代码生成的方法还是要比直接使用new慢了15-40倍,但比使用Activator的方法快20倍左右,比Invoke的方法快10倍左右,因此在不能直接使用new的时候,动态代码生成的方法还是非常实用的。
public abstract class Creator
...{
private static AssemblyBuilder dynamicAssembly = null;
private static ModuleBuilder moduleBuilder = null;
private static Dictionary<Type, Creator> creatorList = new Dictionary<Type, Creator>();
private static ModuleBuilder GetDynamicModule()
...{
if (dynamicAssembly == null)
...{
dynamicAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.Run);
moduleBuilder = dynamicAssembly.DefineDynamicModule("MainModule");
}
return moduleBuilder;
}
private static void CreateMethod(TypeBuilder tb, Type originalType, Object[] param)
...{
MethodInfo mi = typeof(Creator).GetMethod("CreateObject");

MethodBuilder mb = tb.DefineMethod("CreateObject", mi.Attributes & ~MethodAttributes.Abstract, mi.CallingConvention, mi.ReturnType, new Type[] ...{ typeof(Object[]) });
ConstructorInfo[] cis = originalType.GetConstructors();
ConstructorInfo theCi = null;
ParameterInfo[] cpis = null;
foreach(ConstructorInfo ci in cis)
...{
cpis = ci.GetParameters();
if (cpis.Length != param.Length)
continue;
theCi = ci;
for (int i = 0; i < cpis.Length; i++)
...{
if (!(param[i] == null || param[i].GetType() == cpis[i].ParameterType || param[i].GetType().IsSubclassOf(cpis[i].ParameterType)))
...{
theCi = null;
break;
}
}
if (theCi != null)
break;
}
if (theCi == null)
throw new ArgumentException("错误的参数个数或类型");
ILGenerator ilg = mb.GetILGenerator();
for (int i = 0; i < param.Length; i++)
...{
ilg.Emit(OpCodes.Ldarg_1);
ilg.Emit(OpCodes.Ldc_I4, i);
ilg.Emit(OpCodes.Ldelem_Ref);
if (cpis[i].ParameterType.IsValueType)
ilg.Emit(OpCodes.Unbox_Any, cpis[i].ParameterType);
}
ilg.Emit(OpCodes.Newobj, theCi);
ilg.Emit(OpCodes.Ret);
tb.DefineMethodOverride(mb, mi); // 定义方法重载
}
private static Creator GetCreator(Type type, Object[] param)
...{
if(!creatorList.ContainsKey(type))
...{
ModuleBuilder module = GetDynamicModule();
TypeBuilder tb = module.DefineType("__dynamicCreator." + type.FullName, TypeAttributes.Public | TypeAttributes.Class, typeof(Creator));
CreateMethod(tb, type, param);
creatorList.Add(type, (Creator)Activator.CreateInstance(tb.CreateType()));
}
return creatorList[type];
}
public abstract Object CreateObject(Object[] param);
public static Object New(Type type, params Object[] param)
...{
Creator creator = GetCreator(type, param);
return creator.CreateObject(param);
}
}
===============================================
查看本文来源
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。