一个生成接口方法代理的Emit代码,支持泛型方法.
由于该方法是针对自需求编写的,所以不一定适合你的需要,但对于想学习的朋友可以作一个参考.
private void MethodGenerator(ILGenerator il, MethodInfo method)
{
Type[] types = GetParameterTypes(method.GetParameters());
Type[] gtypes;
MethodInfo callmethod;
il.DeclareLocal(typeof(MethodBase));
il.DeclareLocal(typeof(object[]));
bool isvoid = method.ReturnType.ToString() == "System.Void";
if (!isvoid)//定义返回值变量
{
il.DeclareLocal(GetType(method.ReturnType));
}
il.DeclareLocal(typeof(object[]));
il.DeclareLocal(typeof(Type[]));
il.Emit(OpCodes.Nop);
callmethod = typeof(MethodBase).GetMethod("GetCurrentMethod", new Type[0]);
il.Emit(OpCodes.Call, callmethod);
il.Emit(OpCodes.Stloc_0);//把调用GetCurrentMethod的返回值封送到局部变量0里
AddGenericTypes
if (types.Length > 0)//存在方法参数
{
il.Emit(OpCodes.Ldc_I4, types.Length);//加载数组长度
il.Emit(OpCodes.Newarr, typeof(object));//定义数组,并保存以下局部变量中
if (!isvoid)
il.Emit(OpCodes.Stloc_3);
else
il.Emit(OpCodes.Stloc_2);
for (int i = 0; i < types.Length; i++)//将参数加载到局部变量数组里面
{
if (!isvoid)
il.Emit(OpCodes.Ldloc_3);
else
il.Emit(OpCodes.Ldloc_2);
il.Emit(OpCodes.Ldc_I4, i);
il.Emit(OpCodes.Ldarg, i + 1);
if (types[i].IsValueType || types[i].IsGenericParameter || types[i].IsGenericType)
{
//是值类型,泛型参,泛型拖进来打包装箱
il.Emit(OpCodes.Box, GetType(types[i]));
}
il.Emit(OpCodes.Stelem_Ref);
}


if (!isvoid)//加载相关局部变量
il.Emit(OpCodes.Ldloc_3);

else
il.Emit(OpCodes.Ldloc_2);

}
else
{
il.Emit(OpCodes.Ldnull);
}
il.Emit(OpCodes.Stloc_1);
il.Emit(OpCodes.Ldloc_0);//加载method类型变量
if (!isvoid)//加载泛型类型数组变量
il.Emit(OpCodes.Ldloc_S, 4);
else
il.Emit(OpCodes.Ldloc_3);
il.Emit(OpCodes.Ldloc_1);//加载参数数组变量
callmethod = typeof(Context).GetMethod("CallMethod", new Type[] { typeof(MethodBase),typeof(Type[]), typeof(object[]) });
il.Emit(OpCodes.Call, callmethod);//把方法参数和相关信息扔到一个上下文方法处理
if (!isvoid)
{
if (method.ReturnType.IsValueType || method.ReturnType.IsGenericType|| method.ReturnType.IsGenericParameter)
{
//是值类型,泛型参,泛型拖进来脱衣服
il.Emit(OpCodes.Unbox_Any,GetType(method.ReturnType));
}
else
{
il.Emit(OpCodes.Castclass, method.ReturnType);
}
il.Emit(OpCodes.Stloc_2);

il.Emit(OpCodes.Ldloc_2);
}
else
{
il.Emit(OpCodes.Pop);
}
il.Emit(OpCodes.Ret);
}































































































【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架