反射代码集

本文介绍如何使用反射和动态类型创建技术来构建对象、调用方法,并处理继承关系中的父类或嵌套类。此外,还展示了如何解决方法名冲突及参数类型的转换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 获取页面类的类型
if (HostingEnvironment.VirtualPathProvider.FileExists(virtualPath)) {
                    Type compiledType 
= null;
                    
try {
//Compiles a file given its virtual path and returns the compiled type. 
                        compiledType = BuildManager.GetCompiledType(virtualPath);                  
                        
if (compiledType == null){                         
//Processes a file given its virtual path and creates an instance of the result.   
object page = BuildManager.CreateInstanceFromVirtualPath(virtualPath, typeof(System.Web.UI.Page));
                            compiledType 
= page.GetType();
                        }

                    }
调用方法
BindingFlags flags = BindingFlags.Public | BindingFlags.DeclaredOnly;
                
if (_pageMethods) flags |= BindingFlags.Static;
                
else flags |= BindingFlags.Instance;
               MethodInfo methodInfo 
= typeList[i].GetMethods(flags);
object target = null;
            
if (!_methodInfo.IsStatic) target = Activator.CreateInstance(methodData.Owner.TypeData.Type);          
            _methodInfo.Invoke(target, actualParams);
    Type t = Type.GetType("WindowsTest.Form2");
    
object obj = System.Activator.CreateInstance(t);
    MethodInfo mif 
= t.GetMethod("Show");
    mif.Invoke(obj,
null);//or ((Form)obj).Show();

创建对象
using System.Reflection;
1
Assembly assembly 
= Assembly.Load("A") ;A为程序集名称
Type t
= assembly.GetType("A.B.C",true,true) ;A.B.C为类的全称
//动态创建实例
object obj = Activator.CreateInstance (t);

2
System.Reflection.Assembly ass 
= System.Reflection.Assembly.Load(nameSpace);
object obj = ass.CreateInstance(className);
Iobject op 
= (Iobject)obj;//Iobject为抽象类,是className的父类

3
using System.Reflection;
Assembly assembly 
= Assembly.LoadFrom("xxx.dll的路径");
Type[] aa 
= a.GetTypes();

foreach(Type t in aa)
...
{
    
if(t.FullName == "a.b.c")
    ...
{
        
object o = Activator.CreateInstance(t);
    }

}


创建动态类和其实例

private static void EmitConstructor<IServiceInterfaceType>(TypeBuilder typeBuilder, Type baseType)
            
where IServiceInterfaceType : IServiceInterface
        
{
            
//define default constructor
            ConstructorBuilder consBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new Type[] typeof(IServiceContainer) }); //用给定的属性和签名,向类中添加新的构造函数。

            ILGenerator ctorIL 
= consBuilder.GetILGenerator();//获取此构造函数的 ILGenerator(生成 Microsoft 中间语言 (MSIL) 指令。MSIL 用作实时 (JIT) 编译器的输入。)
            ctorIL.Emit(OpCodes.Ldarg_0);  //把this推上堆栈
            
            ctorIL.Emit(OpCodes.Ldarg_1);  
//构建函数的参数
            ctorIL.Emit(OpCodes.Ldtoken, typeof(IServiceInterfaceType)); //传递的标记被转换为 RuntimeHandle 并被推送到堆栈上。
            
            ctorIL.Emit(OpCodes.Call, 
typeof(Type).GetMethod("GetTypeFromHandle", BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public)); //获取由指定类型句柄引用的类型。this.GetTypeFromHandle(IServiceInterfaceType as RuntimeHandle);
            ctorIL.Emit(OpCodes.Call, baseType.GetConstructor(new Type[] typeof(IServiceContainer), typeof(Type) })); //调用this的基类构造函数。
            ctorIL.Emit(OpCodes.Ret);
        }

private IServiceInterfaceType EmitDynamicServiceInterfaceImplType<IServiceInterfaceType>(AssemblyBuilder assBuilder, ModuleBuilder modBuilder)
            
where IServiceInterfaceType : IServiceInterface
        
{
            TypeBuilder typeBuilder 
= modBuilder.DefineType(DYNAMIC_INTERFACEIMPL_NAMESPACE + "." + typeof(IServiceInterfaceType).FullName, TypeAttributes.Public);
            typeBuilder.AddInterfaceImplementation(
typeof(IServiceInterfaceType));  //添加此类型实现的接口。

            Type baseType 
= typeof(BaseServiceInterfaceImpl);
            typeBuilder.SetParent(baseType);  
//设置此 Type 的父类型。

            MethodInfo[] mis 
= typeof(IServiceInterfaceType).GetMethods();

            EmitConstructor
<IServiceInterfaceType>(typeBuilder, baseType);

            EmitMethods
<IServiceInterfaceType>(typeBuilder, baseType, mis);

            
return (IServiceInterfaceType)Activator.CreateInstance(typeBuilder.CreateType(), container);  //创建该type的实例
        }

 


       private static void EmitEntityUpdateOriginalKeyValuesMethod(Type baseType)
        
{
            
//define UpdateOriginalKeyValues()
            MethodInfo mi = typeof(IEntity).GetMethod("UpdateOriginalKeyValues");
            ParameterInfo[] paramInfos 
= mi.GetParameters();
            
int paramlength = paramInfos.Length;
            Type[] paramTypes 
= new Type[paramlength];
            
for (int i = 0; i < paramlength; i++)
            
{
                paramTypes[i] 
= paramInfos[i].ParameterType;
            }

            MethodBuilder updateOriginalKeyValuesMethodBuilder 
= typeBuilder.DefineMethod(mi.Name, mi.Attributes & (~MethodAttributes.Abstract) | MethodAttributes.Public, mi.CallingConvention, mi.ReturnType, paramTypes);
            
for (int i = 0; i < paramlength; i++)
            
{
                ParameterInfo pi 
= paramInfos[i];
                updateOriginalKeyValuesMethodBuilder.DefineParameter(i 
+ 1, pi.Attributes, pi.Name);
            }

            typeBuilder.DefineMethodOverride(updateOriginalKeyValuesMethodBuilder, mi);
            ILGenerator updateOriginalKeyValueslMethodIL 
= updateOriginalKeyValuesMethodBuilder.GetILGenerator();

            updateOriginalKeyValueslMethodIL.Emit(OpCodes.Ldarg_0);
            updateOriginalKeyValueslMethodIL.Emit(OpCodes.Callvirt, baseType.GetMethod(
"UpdateOriginalKeyValues", BindingFlags.Instance | BindingFlags.NonPublic));
            updateOriginalKeyValueslMethodIL.Emit(OpCodes.Ret);
        }

Type baseType = typeof(Entity<IEntityType>);

namespace NBear.Common
{
      [Serializable]
    
public abstract class Entity<IEntityType>
        
where IEntityType : IEntity
    
{
         
protected void UpdateOriginalKeyValues()
        
{
            
if (originalKeyValues != null)
            
{
                originalKeyValues 
= keyValues.Clone();
            }

        }

}

获取对象

public IEntityType Get<IEntityType>(object id)
            
where IEntityType : IEntity
        
{
            
string[] primaryKeys = Entity<IEntityType>.GetPrimaryKeyColumnNames();
            
if (primaryKeys.Length != 1)
            
{
                
throw new NotSupportedException("Gateway.Get<IEntityType>(object id) only supports entities with single primary key.");
            }

            IDataReader reader 
= SimpleDbHelper.SelectReadOnly(
                db, ParseTableName(Entity
<IEntityType>.GetTableName()), Entity<IEntityType>.GetColumnNames(),
                BuildCombinedWhere
<IEntityType>(BuildDbColumnName(primaryKeys[0]) + " = " + BuildDbParamName(primaryKeys[0])), new object[] { id }null);
            
if (!reader.Read())
            
{
                
return default(IEntityType);
            }

            IEntityType obj 
= EntityFactory<IEntityType>.CreateObject(reader, true);
            reader.Close();
            
return obj;
        }

public static IEntityType CreateObject(IDataReader reader, bool readColumnByIndex)
        
{
            Check.Require(reader 
!= nullnullnew ArgumentNullException("reader"));

            
return readColumnByIndex ? CreateObjectByColumnIndex(reader) : CreateObjectByColumnName(reader);
        }

private static IEntityType CreateObjectByColumnName(IDataReader reader)
        
{
            IEntityType retObj 
= EntityFactory<IEntityType>.CreateObject();
            KeyValueCollection keyValues 
= retObj.GetKeyValues();
            
string[] keys = keyValues.GetKeys();
            
            
for (int i = 0; i < keyValues.GetKeys().Length; i++)
            
{
                
try
                
{
                    
object val = reader.GetValue(reader.GetOrdinal(keys[i]));
                    
if (val != DBNull.Value)
                    
{
                        keyValues[i] 
= val;
                    }

                }

                
catch
                
{
                    
//if column not in this query, just skip
                }

            }

            
return retObj;
        }

private static IEntityType CreateObjectByColumnIndex(IDataReader reader)
        
{
            IEntityType retObj 
= EntityFactory<IEntityType>.CreateObject();
            KeyValueCollection keyValues 
= retObj.GetKeyValues();
            
for (int i = 0; i < keyValues.GetKeys().Length; i++)
            
{
                
object val = reader.GetValue(i);
                
if (val != DBNull.Value)
                
{
                    keyValues[i] 
= val;
                }

            }

            
return retObj;
        }

 
public static IEntityType CreateObject()//创建动态类对象
        {
            
return (IEntityType)Activator.CreateInstance(GetDynamicEntityType());
        }

public static Type GetDynamicEntityType() //获取动态类
        {
            Type t 
= null;

            
if (customEntities.ContainsKey(typeof(IEntityType)))
            
{
                t 
= customEntities[typeof(IEntityType)];
            }


            
if (t != null)
            
{
                
return t;
            }


            
try
            
{
                t 
= assBuilder.GetType(DYNAMIC_ENTITY_NAMESPACE + "." + typeof(IEntityType).FullName);
            }

            
catch
            
{
            }


            
if (t != null)
            
{
                
return t;
            }

            
else
            
{
                
return typeBuilder.CreateType();
            }

        }

属性方法创建

private static void EmitEntityProperties(Type keyValuesType, Type baseType, PropertyInfo[] pis)
        
{
            
//define properties
            for (int i = 0; i < pis.Length; i++)
            
{
                PropertyInfo pi 
= pis[i];
                PropertyBuilder propBuilder 
= typeBuilder.DefineProperty(pi.Name, System.Reflection.PropertyAttributes.HasDefault, pi.PropertyType, null);
                MethodAttributes getSetAttr 
= MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig;

                CustomPropertyAttribute c 
= (GetEntityConfiguration() == null ? null : GetEntityConfiguration().GetCustomProperty(pi.Name));

                
object[] customPropertyAttrs = (c == null ? pi.GetCustomAttributes(typeof(CustomPropertyAttribute), false) : new object[] { c });

                
if (customPropertyAttrs != null && customPropertyAttrs.Length > 0)
                
{
                    
//define custom property
                    CustomPropertyAttribute cpa = (CustomPropertyAttribute)customPropertyAttrs[0];
                    
                    MethodBuilder getPropMethodBuilder 
= typeBuilder.DefineMethod("get_" + pi.Name, pi.GetGetMethod().Attributes & (~MethodAttributes.Abstract) | getSetAttr, pi.PropertyType, Type.EmptyTypes);
                    typeBuilder.DefineMethodOverride(getPropMethodBuilder, pi.GetGetMethod());
                    ILGenerator getPropMethodIL 
= getPropMethodBuilder.GetILGenerator();
                    getPropMethodIL.DeclareLocal(
typeof(string[]));

                    
//load keyValues field
                    getPropMethodIL.Emit(OpCodes.Ldarg_0);
                    getPropMethodIL.Emit(OpCodes.Ldfld, baseType.GetField(
"keyValues", BindingFlags.Instance | BindingFlags.NonPublic));

                    
if (cpa.Parameters != null && cpa.Parameters.Length > 0)
                    
{
                        
//create parms string array
                        EmitLoadInt32Value(getPropMethodIL, cpa.Parameters.Length);
                        getPropMethodIL.Emit(OpCodes.Newarr, 
typeof(string));
                        getPropMethodIL.Emit(OpCodes.Stloc_0);

                        
int j = 0;
                        
foreach (string p in cpa.Parameters)
                        
{
                            getPropMethodIL.Emit(OpCodes.Ldloc_0);
                            EmitLoadInt32Value(getPropMethodIL, j);
                            getPropMethodIL.Emit(OpCodes.Ldstr, p);
                            getPropMethodIL.Emit(OpCodes.Stelem_Ref);

                            j
++;
                        }

                    }

                    
else
                    
{
                        
//create an empty parms string array
                        EmitLoadInt32Value(getPropMethodIL, 0);
                        getPropMethodIL.Emit(OpCodes.Newarr, 
typeof(string));
                        getPropMethodIL.Emit(OpCodes.Stloc_0);
                    }


                    getPropMethodIL.Emit(OpCodes.Ldloc_0);
                    getPropMethodIL.Emit(OpCodes.Newobj, pi.PropertyType.GetConstructor(
new Type[] typeof(KeyValueCollection), typeof(string[]) }));
                    getPropMethodIL.Emit(OpCodes.Ret);
                    propBuilder.SetGetMethod(getPropMethodBuilder);
                }

                
else
                
{
                    
//define standard property
                    if (pi.CanRead)
                    
{
                        
//define getMethod
                        MethodBuilder getPropMethodBuilder = typeBuilder.DefineMethod("get_" + pi.Name, pi.GetGetMethod().Attributes & (~MethodAttributes.Abstract) | getSetAttr, pi.PropertyType, Type.EmptyTypes);
                        typeBuilder.DefineMethodOverride(getPropMethodBuilder, pi.GetGetMethod());
                        ILGenerator getPropMethodIL 
= getPropMethodBuilder.GetILGenerator();
                        getPropMethodIL.Emit(OpCodes.Ldarg_0);
                        getPropMethodIL.Emit(OpCodes.Ldfld, baseType.GetField(
"keyValues", BindingFlags.Instance | BindingFlags.NonPublic));
                        EmitLoadInt32Value(getPropMethodIL, i);
                        getPropMethodIL.Emit(OpCodes.Callvirt, keyValuesType.GetMethod(
"get_Item"new Type[] typeof(int) }));
                        
if (pi.PropertyType.IsValueType)
                        
{
                            getPropMethodIL.Emit(OpCodes.Unbox_Any, pi.PropertyType);
                        }

                        
else
                        
{
                            getPropMethodIL.Emit(OpCodes.Castclass, pi.PropertyType);
                        }

                        getPropMethodIL.Emit(OpCodes.Ret);
                        propBuilder.SetGetMethod(getPropMethodBuilder);
                    }


                    
if (pi.CanWrite)
                    
{
                        
//define setMethod
                        MethodBuilder setPropMethodBuilder = typeBuilder.DefineMethod("set_" + pi.PropertyType, pi.GetSetMethod().Attributes & (~MethodAttributes.Abstract) | getSetAttr, nullnew Type[] { pi.PropertyType });
                        typeBuilder.DefineMethodOverride(setPropMethodBuilder, pi.GetSetMethod());
                        ILGenerator setPropMethodIL 
= setPropMethodBuilder.GetILGenerator();
                        setPropMethodIL.Emit(OpCodes.Ldarg_0);
                        setPropMethodIL.Emit(OpCodes.Callvirt, baseType.GetMethod(
"CheckOriginalKeyValues", BindingFlags.Instance | BindingFlags.NonPublic));
                        setPropMethodIL.Emit(OpCodes.Ldarg_0);
                        setPropMethodIL.Emit(OpCodes.Ldfld, baseType.GetField(
"keyValues", BindingFlags.Instance | BindingFlags.NonPublic));
                        EmitLoadInt32Value(setPropMethodIL, i);
                        setPropMethodIL.Emit(OpCodes.Ldarg_1);
                        
if (pi.PropertyType.IsValueType)
                        
{
                            setPropMethodIL.Emit(OpCodes.Box, pi.PropertyType);
                        }

                        setPropMethodIL.Emit(OpCodes.Callvirt, keyValuesType.GetMethod(
"set_Item"new Type[] typeof(int), typeof(object) }));
                        setPropMethodIL.Emit(OpCodes.Ret);
                        propBuilder.SetSetMethod(setPropMethodBuilder);
                    }

                }

            }

        }

方法调用
public static object CallByName(
      
object target, string methodName, CallType callType, 
      
params object[] args)
    
{
      
switch (callType)
      
{
        
case CallType.Get:
          
{
            PropertyInfo p 
= target.GetType().GetProperty(methodName);
            
return p.GetValue(target, args);
          }

        
case CallType.Let:
        
case CallType.Set:
          
{
            PropertyInfo p 
= target.GetType().GetProperty(methodName);
            
object[] index = null;
            args.CopyTo(index, 
1);
            p.SetValue(target, args[
0], index);
            
return null;
          }

        
case CallType.Method:
          
{
            MethodInfo m 
= target.GetType().GetMethod(methodName);
            
return m.Invoke(target, args);
          }

      }

      
return null;
    }

获取父类或嵌套类的上级
private static object CreateBusinessObject(object criteria)
    
{
      Type businessType;
      
if (criteria.GetType().IsSubclassOf(typeof(CriteriaBase))) //判断其父类
      {
        
// get the type of the actual business object
        
// from CriteriaBase 
        businessType = ((CriteriaBase)criteria).ObjectType;
      }

      
else
      
{
        
// get the type of the actual business object
        
// based on the nested class scheme in the book
        businessType = criteria.GetType().DeclaringType;  //获取当前嵌套类的上一层类的类别
      }


      
// create an instance of the business object
      return Activator.CreateInstance(businessType, true);
    }


递归向上寻找方法
public static MethodInfo FindMethod(Type objType, string method, Type[] types)
    
{
      MethodInfo info 
= null;
      
do
      
{
        
//find for a strongly typed match
        info = objType.GetMethod(method, oneLevelFlags, null, types, null);
        
if (info != null)
          
break;  //match found

        objType 
= objType.BaseType;
      }
 while (objType != null);

      
return info;
    }
 const BindingFlags allLevelFlags =
      BindingFlags.FlattenHierarchy 
|
      BindingFlags.Instance 
|
      BindingFlags.Public 
|
      BindingFlags.NonPublic;

    
const BindingFlags oneLevelFlags =
      BindingFlags.DeclaredOnly 
|
      BindingFlags.Instance 
|
      BindingFlags.Public 
|
      BindingFlags.NonPublic;
根据名字找,和冲突解决
try
        

          result 
= objectType.GetMethod(method, allLevelFlags); 
        }

        
catch (AmbiguousMatchException)
        
{
          MethodInfo[] methods 
= objectType.GetMethods();
          
foreach (MethodInfo m in methods)
            
if (m.Name == method && m.GetParameters().Length == parameters.Length)
            
{
              result 
= m;
              
break;
            }

          
if (result == null)
            
throw;
        }


/
将参数转成需要的类型,供助TypeDescriptor自动获得类型转换器
  
//通过反射得到类型信息
                type =  System.Type.GetType(typeName, falsetrue);
                
if (type == null)
                
{
                    
//处理ASP.NET的临时生成类
                    type = BuildManager.GetType(typeName, falsetrue);
                }

ParameterInfo[] paraInfos 
= method.GetParameters();
 
object[] paras = new object[paraInfos.Length];
 
//将参数转成需要的类型,供助TypeDescriptor自动获得类型转换器
aras[i] = TypeDescriptor.GetConverter(paraInfos[i].ParameterType).ConvertFromString(parameterValues[i]);
 给接口类创建方法
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值