一个生成接口方法代理的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);
            
            
        }

posted on 2008-05-22 09:11  henry  阅读(1555)  评论(5编辑  收藏  举报

导航