/// <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>(); })); }
/// <summary> /// 创建属性的获取器委托。 /// </summary> /// <param name="propertyInfo">属性元数据。</param> /// <returns>属性获取器的委托。</returns> public static DynamicMemberGetter CreatePropertyGetter(this PropertyInfo propertyInfo) { if (propertyInfo == null) { throw new ArgumentNullException(nameof(propertyInfo)); } return(GetterCache.GetOrAdd(propertyInfo, m => { var declaringType = propertyInfo.DeclaringType; var methodInfo = propertyInfo.GetGetMethod(true); if (methodInfo == null) { return null; } var emit = new EmitHelper(DefineTypes.Object, new Type[] { DefineTypes.Object }, declaringType); var isStatic = methodInfo.IsStatic; if (!isStatic) { emit.ldarg_0 .castType(declaringType) .callvirt(methodInfo) .end(); } else { emit.call(methodInfo) .end(); } emit.boxIfValueType(propertyInfo.PropertyType) .ret(); return emit.CreateDelegate <DynamicMemberGetter>(); })); }