C#反射机制详解


反射的定义:审查元数据并收集关於它的类型信息的能力,元数据(编辑后的基本数据单元)就是一大堆表,编译器会创建一个类定义表,一个字段定义表,一个方法定义表等,System.Reflection命名空间包含的几个类,允许你反射(解析)这些元数据的代码

一、反射的作用:
动态的创建类型的实例,将类型邦定到现有对象,或从现有对象中获取类型 
应用程序需要在运行时从某个特定的程序集中载入一个特定的类型,以便实现某个任务时可以用到反射 
反射主要应用於类库,这些类库需要知道一个类型的定义,以便提供更多的功能

二、应用要点:
现实应用程序中很少使用到反射 
使用反射动态邦定需要牺牲性能 
有些元数据信息是不能通过反射获取的 
某些反射类型是专门為那些CLR开发编辑器开发使用的,所以你要意思到不是所有反射类型都是可以使用的

三、取得Assembly的方法:
Assembly.Load 
Assembly.LoadFile 
Assembly.LoadFrom 
Type对象的Assembly方法

四、反射的成员:
MemberInfo-成员 
ConstructorInfo-结构 
FieldInfo-字段 
MethodInfo-方法 
PropertyInfo-属性 
EventInfo-事件

五、根据反射取得对象的Member信息
private  void WriteReflectionInfo()
{
Type testType =  typeof(Test);
Assembly assembly = testType.Assembly;
Response.Write( " Assembly: " + assembly.FullName +  " <br/> ");
Type[] typeList = assembly.GetTypes();    //  获取类型
//  针对每个类型获取详细信息
foreach (Type type  in typeList)
{
    Response.Write( " ------------------------ " + type.Namespace + type.Name +  " ------------------------<br/> ");
     //  获得类型的结构信息
    ConstructorInfo[] constructs = type.GetConstructors();

     //  获得类型的字段信息
    FieldInfo[] fields = type.GetFields();
    Response.Write( " <b>类的公共字段信息如下:</b> " +  " <br/> ");
     int a1 =  1;
     foreach (FieldInfo field  in fields)
    {
        Response.Write((a1++).ToString() +  " " + field.Name +  " <br/> ");
    }

     //  获得方法信息
    MethodInfo[] methods = type.GetMethods();

    Response.Write( " <b>类的公共方法如下:</b> " +  " <br/> ");
     int a2 =  1;
     foreach (MethodInfo method  in methods)
    {
        ParameterInfo[] parameters = method.GetParameters();
        ParameterInfo reparam = method.ReturnParameter;
        Response.Write((a2++).ToString() +  " " + reparam.ParameterType.Name +  "   " + method.Name +  " ( ");
         int index =  0;
         foreach (ParameterInfo para  in parameters)
        {
             if (index++ < parameters.Length -  1)
                Response.Write(para.ParameterType.Name +  "   " + para.Name +  " , ");
             else
                Response.Write(para.ParameterType.Name +  "   " + para.Name);
        }
        Response.Write( " )<br/> ");
    }

     //  获得属性的信息
    PropertyInfo[] propertys = type.GetProperties();

    Response.Write( " <b>类的公共属性如下:</b> " +  " <br/> ");
     int a3 =  1;
     foreach (PropertyInfo pro  in propertys)
    {
        Response.Write((a3++).ToString() +  " " + pro.PropertyType.Name +  "   " + pro.Name +  " { ");
         if (pro.CanRead) Response.Write( " get; ");
         if (pro.CanWrite) Response.Write( " set; ");
        Response.Write( " }<br/> ");
    }
     //  获得事件信息
    EventInfo[] events = type.GetEvents();

    Response.Write( " <b>类的成员如下:</b> " +  " <br/> ");
     //  获得成员
     int a4 =  1;
     foreach (MemberInfo mi  in type.GetMembers())
    {
        Response.Write((a4++).ToString() +  " " + mi.MemberType.ToString() +  "  :  " + mi.Name +  " <br/> ");
    }
}

六、动态创建对象
Assembly对象的 CreateInstance方法 
Activator. CreateInstance方法 
Type对象的 InvokeMember方法
//  使用Assembly的CreateInstance方法来取得对象的实例
private  void Assembly_CreateInstance()
{
     string assemblyName =  " SqlModel ";
     string className = assemblyName +  " .Member ";
     //  创建无参数实例
    IDAL.IMember member = (IDAL.IMember)Assembly.Load(assemblyName).CreateInstance(className);
    Response.Write( " 创建无参数实例: " + member.ID +  " <br/> ");
     //  创建有参数实例
    Object[] parameters =  new Object[ 1];
    parameters[ 0] =  10000;
    IDAL.IMember member1 = (IDAL.IMember)Assembly.Load(assemblyName).CreateInstance(className,  false, BindingFlags.Default,  null, parameters,  nullnull);
    Response.Write( " 创建有参数实例: " + member1.ID +  " <br/> ");
}

//  使用Activator的CreateInstance方法来取得对象的实例
private  void Activator_CreateInstance()
{
     string assemblyName =  " SqlModel ";
     string className = assemblyName +  " .Member ";
     //  创建无参数实例
    System.Runtime.Remoting.ObjectHandle obj = Activator.CreateInstance(assemblyName, className);
    IDAL.IMember member = (IDAL.IMember)obj.Unwrap();
    Response.Write( " 创建无参数实例: " + member.ID +  " <br/> ");
     //  创建有参数实例
    Object[] parameters =  new Object[ 1];
    parameters[ 0] =  10000;
    System.Runtime.Remoting.ObjectHandle obj1 = Activator.CreateInstance(assemblyName, className,  false, BindingFlags.CreateInstance,  null, parameters,  nullnullnull);
    IDAL.IMember member1 = (IDAL.IMember)obj1.Unwrap();
    Response.Write( " 创建有参数实例: " + member1.ID +  " <br/> ");
}

//  使用Type的InvokeMember方法来取得对象的实例
private  void Type_InvokeMember()
{
     string assemblyName =  " SqlModel ";
     string className = assemblyName +  " .Member ";
    Assembly assem = Assembly.Load(assemblyName);
    Type type = assem.GetType(className);    //  註意这里如果使用Type.GetType来取得Type的话,那麼assemblyName指定的类一定要是强命名的
    
//  创建无参数实例
    IDAL.IMember member = (IDAL.IMember)type.InvokeMember(className, BindingFlags.CreateInstance,  nullnullnull);
    Response.Write( " 创建无参数实例: " + member.ID +  " <br/> ");
     //  创建有参数实例
    Object[] parameters =  new Object[ 1];
    parameters[ 0] =  10000;
    IDAL.IMember member1 = (IDAL.IMember)type.InvokeMember(className, BindingFlags.CreateInstance,  nullnull, parameters);
    Response.Write( " 创建有参数实例: " + member1.ID +  " <br/> ");
}

七、动态调用对象方法

Type对象的 InvokeMember方法 
MethodInfo对象的Invoke方法
//  Type对象的 InvokeMember方法来动态调用方法
private  void InvokeMember()
{
     string assemblyName =  " SqlModel ";
     string className = assemblyName +  " .Member ";
     string methodName = String.Empty;
     string result = String.Empty;
    Assembly assem = Assembly.Load(assemblyName);
    Object obj = assem.CreateInstance(className);
    Type type = assem.GetType(className);    //  註意这里如果使用Type.GetType来取得Type的话,那麼assemblyName指定的类一定要是强命名的
    
//  动态调用无参数的方法
    methodName =  " GetName ";
    result = ( string)type.InvokeMember(methodName, BindingFlags.InvokeMethod,  null, obj,  null);
    Response.Write(methodName +  " 方法的返回值: " + result +  " <br/> ");
     //  动态调用有参数的方法
    methodName =  " Update ";
    Object[] methodParams =  new Object[ 1];
    methodParams[ 0] = DateTime.Now;
    result = ( string)type.InvokeMember(methodName, BindingFlags.InvokeMethod,  null, obj, methodParams);
    Response.Write(methodName +  " 方法的返回值: " + result +  " <br/> ");
     //  动态调用参数构架函数的带有参数的方法
    Object[] parameters =  new Object[ 1];
    parameters[ 0] =  10000;
    obj = assem.CreateInstance(className, false,BindingFlags.CreateInstance,  null, parameters,  nullnull);
    result = ( string)type.InvokeMember(methodName, BindingFlags.InvokeMethod,  null, obj, methodParams);
    Response.Write(methodName +  " 方法的返回值: " + result +  " <br/> ");
}

//  MethodInfo对象的Invoke方法来动态调用方法

private  void MethodInfo_Invoke()
{
     string assemblyName =  " SqlModel ";
     string className = assemblyName +  " .Member ";
     string methodName = String.Empty;
     string result = String.Empty;

    Assembly assem = Assembly.Load(assemblyName);
    Object obj = assem.CreateInstance(className);
    Type type = assem.GetType(className);    //  註意这里如果使用Type.GetType来取得Type的话,那麼assemblyName指定的类一定要是强命名的
    
//  动态调用无参数的方法
    methodName =  " GetName ";
    MethodInfo methodInfo = type.GetMethod(methodName);
    result = ( string)methodInfo.Invoke(obj,  null);
    Response.Write(methodName +  " 方法的返回值: " + result +  " <br/> ");
     //  动态调用有参数的方法
    methodName =  " Update ";
    Object[] methodParams =  new Object[ 1];
    methodParams[ 0] = DateTime.Now;
    MethodInfo method = type.GetMethod(methodName);
    result = ( string)method.Invoke(obj, methodParams);
    Response.Write(methodName +  " 方法的返回值: " + result +  " <br/> ");
}

--------------------------------------------------------------------------------
以上所使用的SqlModel.Member為:
新建一个SqlModel类库,在其下建立一个Member的类

namespace SqlModel
{
     public  class Member : IDAL.IMember
    {
         private  int _id =  100;
         public  int ID
        {
             get {  return _id; }
             set { _id = value; }
        }
         private  string _name =  " limin ";
         public  string Name
        {
             get {  return _name; }
             set { _name = value; }
        }

         public Member() { }
         public Member( int id)
        {
            _id = id;
        }

         private  void Init()
        { }

         public  string GetName()
        {
             return _name;
        }
         public  string Update (DateTime cdate)
        {
             return  " { " + String.Format( " ID:{0},Name:{1},CreateDate:{2} ",_id,_name,cdate) +  " } ";
        }
    }
}


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM