首页 > 技术文章 > 含有ref out 参数 的方法反射 Emit 与 普通

kubimiantiao 2015-06-08 17:08 原文

反射中很多朋友应该屡屡被带有ref out参数的方法折腾

当使用正常反射一个方法时候:

 代码如下调用一个后期绑定方法MakeByRefType 就行了

MemberInfo test = typeof(Type).GetMethod("MemberName", new Type[] { typeof(int), typeof(int).MakeByRefType()});

 

当使用Emit 动态创建方法 这个方法还需要反射其他方法时候:

 比正常方式麻烦一点的是 .NET 会将类型修改为 XXX&  比如 int&

首先你还是要以正常的方式创建 Type[]  判断类型名包含 & 先以  XXX 类型 

OpCodes.Ldtoken 是无法获取到  ref out 参数的 元数据标记的运行时表示形态

先以除去& 的类型获取后

在调用Type.MakeByRefType() 方法

.... 
       var methodInfoLocal = generator.DeclareLocal(typeof(System.Reflection.MethodInfo));
       var preAspectLocal = generator.DeclareLocal(typeof(PreAspectAttribute));
       var Typeparmeter = generator.DeclareLocal(typeof(Type[]));

            generator.Emit(OpCodes.Ldc_I4, parameterInfos.Length);
            generator.Emit(OpCodes.Newarr, typeof(Type));
            generator.Emit(OpCodes.Stloc, Typeparmeter);

            for ( int i = 0; i < parameterInfos.Length; i++ )
            {
                generator.Emit(OpCodes.Ldloc, Typeparmeter);
                generator.Emit(OpCodes.Ldc_I4, i); 
if ( parameterInfos[i].ParameterType.Name.Contains("&") ) { string typstr = parameterInfos[i].ParameterType.FullName.Replace("&", ""); Type typetem = Type.GetType(typstr); generator.Emit(OpCodes.Ldtoken, typetem); } else { generator.Emit(OpCodes.Ldtoken, parameterInfos[i].ParameterType); } generator.Emit(OpCodes.Call, typeof(System.Type).GetMethod("GetTypeFromHandle", new Type[] { typeof(System.RuntimeTypeHandle) })); if ( parameterInfos[i].ParameterType.Name.Contains("&") ) { generator.Emit(OpCodes.Callvirt, typeof(System.Type).GetMethod("MakeByRefType")); } generator.Emit(OpCodes.Stelem_Ref); } generator.Emit(OpCodes.Ldarg_0); //构造中实例化的对象 generator.Emit(OpCodes.Ldfld, _realProxyField); generator.Emit(OpCodes.Callvirt, typeof(System.Object).GetMethod("GetType", BindingFlags.Public | BindingFlags.Instance)); generator.Emit(OpCodes.Ldstr, methodName); generator.Emit(OpCodes.Ldloc, Typeparmeter); generator.Emit(OpCodes.Callvirt, typeof(System.Type).GetMethod("GetMethod", new Type[] { typeof(string),typeof(Type[]) })); .......

 

 

推荐阅读