/// <summary> /// 创建指定 <paramref name="constructorInfo"/> 的动态构造函数。 /// </summary> /// <param name="constructorInfo">构造函数的元数据。</param> /// <returns>绑定到实例构造函数的委托。</returns> public static DynamicConstructorHandler CreateConstructorHandler(this ConstructorInfo constructorInfo) { if (constructorInfo == null) { throw new ArgumentNullException(nameof(constructorInfo)); } return(ConstructorCache.GetOrAdd(constructorInfo, m => { var declaringType = m.DeclaringType; var emit = new EmitHelper(DefineTypes.Object, new Type[] { DefineTypes.ObjectArray }, declaringType); var parameterInfos = m.GetParameters(); var parameterLength = parameterInfos.Length; var parameterLocals = new LocalBuilder[parameterLength]; var hasByRef = false; CreateParameterLocals(0, emit, parameterInfos, parameterLength, parameterLocals, ref hasByRef); LoadParameterLocals(emit, parameterInfos, parameterLength, parameterLocals); emit.newobj(m) .boxIfValueType(declaringType) .end(); if (hasByRef) { SaveParameters(0, emit, parameterInfos, parameterLength, parameterLocals); } emit.ret().end(); return emit.CreateDelegate <DynamicConstructorHandler>(); })); }
/// <summary> /// 创建方法的调用委托。 /// </summary> /// <param name="methodInfo">方法元数据。方法不能是一个尚未构造泛型参数的方法</param> /// <returns>方法调用的委托。</returns> public static DynamicMethodInvoker CreateMethodInvoker(this MethodInfo methodInfo) { if (methodInfo == null) { throw new ArgumentNullException(nameof(methodInfo)); } if (methodInfo.IsGenericMethodDefinition) { throw new ArgumentException("不支持尚未构造泛型参数的方法。", nameof(methodInfo)); } return(MethodCache.GetOrAdd(methodInfo, m => { var declaringType = m.DeclaringType; var emit = new EmitHelper(DefineTypes.Object, new Type[] { DefineTypes.Object, DefineTypes.ObjectArray }, declaringType); var isStatic = m.IsStatic; var returnType = m.ReturnType; //- 方法的返回类型 var parameterInfos = m.GetParameters(); //- 方法的参数集合 var parameterLength = parameterInfos.Length; var parameterLocals = new LocalBuilder[parameterLength]; var hasByRef = false; CreateParameterLocals(1, emit, parameterInfos, parameterLength, parameterLocals, ref hasByRef); if (!isStatic) { emit.ldarg_0 .castType_any(declaringType) .end(); } LoadParameterLocals(emit, parameterInfos, parameterLength, parameterLocals); emit.call(isStatic, m); if (returnType == typeof(void)) { emit.ldnull .end(); } else { emit.boxIfValueType(returnType) .end(); } if (hasByRef) { SaveParameters(1, emit, parameterInfos, parameterLength, parameterLocals); } emit.ret().end(); return emit.CreateDelegate <DynamicMethodInvoker>(); })); }