zoukankan      html  css  js  c++  java
  • c# 反射的用法 转

    在网上查找了不少的资料,可以说大同小异,概念性的东西网上一搜一堆,
    今天把反射的东西整理了一下,供大家使用,我保证我这里是最全面的东西,当然也是基础的东西,
    在学好了这一切的基础上,大家可以学习反射的具体插件等应用,老鸟就不用看了.
    首先我们建立一个类库,将它生成为HelloWorld.dll,
    using System;

     
    namespace Webtest
     
    {

        
    public interface interface1
         
    {
              
    int add();
         
         }

         
    public class ReflectTest:interface1
         
    {
             
             
    public String Write;
             
    private String Writec;

             
    public String Writea
             
    {
                 
    get
                 
    {
                     
    return Write;
                 }

                 
    set
                 
    {
                     Write 
    = value;
                 }

             
             }


             
    private String Writeb
             
    {
                 
    get
                 
    {
                     
    return Writec;
                 }

                 
    set
                 
    {
                     Writec 
    = value;
                 }


             }


              
    public ReflectTest()
              
    {
                  
    this.Write = "Write";
                  
    this.Writec = "Writec";
              }


             
    public ReflectTest(string str1,string str2)
             
    {
                 
    this.Write = str1;
                 
    this.Writec = str2;
             }


             
    public string WriteString(string s,int b)
             
    {
                 
    return "欢迎您," + s + "---" + b; ;
             }


              
    public static string WriteName(string s)
              
    {
                 
    return "欢迎您光临," + s;
              }


             
    public string WriteNoPara()
             
    {
                
    return "您使用的是无参数方法";
             }


             
    private string WritePrivate()
             
    {
                 
    return "私有类型的方法";
             }



             
    public int add()
             
    {
                 
    return 5;
             }

         }

    }
    然后,建立再建立一个项目引入该HelloWorld.dll,
    using System;

    using System.Threading;
    using System.Reflection;


    class Test
    {
        
    delegate string TestDelegate(string value,int value1);

       
    static void Main()
        
    {
            
    //Assembly t = Assembly.LoadFrom("HelloWorld.dll"); 与下面相同的效果
            Assembly t = Assembly.Load("HelloWorld");

    //**********************************************************************     
           foreach (Type aaa in t.GetTypes())
           
    {
                
    //Console.Write(aaa.Name);   //显示该dll下所有的类
            }


    //**********************************************************************
            Module[] modules = t.GetModules();

            
    foreach (Module module in modules)
            
    {
                
    //Console.WriteLine("module name:" + module.Name);//显示模块的名字本例为"HelloWorld.dll"
            }


    //**********************************************************************
            Type a = typeof(Webtest.ReflectTest);//得到具体的类的类型,和下面一个效果
            
    //Type a = t.GetType("Webtest.ReflectTest");//
            
    //Console.Write(a.Name);

    //**********************************************************************
            string[] bb ="aaaa""bbbbb" };
            
    object obj = Activator.CreateInstance(a,bb); //创建该类的实例,后面的bb为有参构造函数的参数
            
    //object obj = t.CreateInstance("Webtest.ReflectTest");//与上面方法相同

    //**********************************************************************        
            MethodInfo[] miArr = a.GetMethods();
            
    foreach (MethodInfo mi0 in miArr)
           
    {
                
    //Console.Write(mi0.Name);  //显示所有的共有方法
           }


    //**********************************************************************
            MethodInfo mi = a.GetMethod("WriteString");//显示具体的方法
            object[] aa={"使用的是带有参数的非静态方法",2};
            
    string s = (string)mi.Invoke(obj,aa); //带参数方法的调用

            MethodInfo mi1 
    = a.GetMethod("WriteName");
            String[] aa1 
    ={"使用的是静态方法"};
            
    string s1 = (string)mi1.Invoke(null, aa1); //静态方法的调用

            MethodInfo mi2 
    = a.GetMethod("WriteNoPara");
            
    string s2 = (string)mi2.Invoke(obj, null); //不带参数的方法调用

            MethodInfo mi3 
    = a.GetMethod("WritePrivate",BindingFlags.Instance | BindingFlags.NonPublic);
            
    string s3 = (string)mi3.Invoke(obj, null); //私有类型方法调用

            
    //Console.Write(s3);

    //**********************************************************************
            PropertyInfo[] piArr = a.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
            
    foreach (PropertyInfo pi in piArr)
            
    {
             
    //Console.Write(pi.Name);  //显示所有的属性
            }


    //**********************************************************************
            PropertyInfo pi1=a.GetProperty("Writea");
            
    //pi1.SetValue(obj, "Writea", null);
            
    //Console.Write(pi1.GetValue(obj,null));

            PropertyInfo pi2 
    = a.GetProperty("Writeb", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
            pi2.SetValue(obj, 
    "Writeb"null);
            
    //Console.Write(pi2.GetValue(obj, null));

            FieldInfo fi1 
    = a.GetField("Write");
            
    //Console.Write(fi1.GetValue(obj));

    //**********************************************************************
            ConstructorInfo[] ci1 = a.GetConstructors();
            
    foreach (ConstructorInfo ci in ci1)
            
    {
                
    //Console.Write(ci.ToString()); //获得构造函数的形式
            }


            ConstructorInfo asCI 
    = a.GetConstructor(new Type[] typeof(string), typeof(string) });
            
    //Console.Write(asCI.ToString());

    //**********************************************************************
            Webtest.interface1 obj1 = (Webtest.interface1)t.CreateInstance("Webtest.ReflectTest");
            Webtest.ReflectTest obj2 
    = (Webtest.ReflectTest)t.CreateInstance("Webtest.ReflectTest");
            
    //Console.Write(obj1.add());典型的工厂模式

    //**********************************************************************
            foreach (Type tt in t.GetTypes())
            
    {
                
    if (tt.GetInterface("interface1")!=null)
                
    {
                    Webtest.interface1 obj3 
    = (Webtest.interface1)Activator.CreateInstance(a);
                    
    //Console.Write(obj3.add());
                }

            }


    //**********************************************************************
            TestDelegate method = (TestDelegate)Delegate.CreateDelegate(typeof(TestDelegate), obj, "WriteString");
           //动态创建委托的简单例子
            
    //Console.Write(method("str1", 2));

    //**********************************************************************
            ConstructorInfo asCI1 = a.GetConstructor(new Type[0]);
            Webtest.ReflectTest obj5 
    = (Webtest.ReflectTest)asCI1.Invoke(null);
                //
    通过无参构造函数实例化的方法
            
    //Console.Write(obj5.Writea);

            ConstructorInfo asCI2 
    = a.GetConstructor(new Type[] typeof(string), typeof(string) });
              //
    通过有参构造函数实例化的方法
            Webtest.ReflectTest obj6 = (Webtest.ReflectTest)asCI2.Invoke(bb);
            Console.Write(obj6.Writea);
    //**********************************************************************

            Console.Read();
        }
       
    }

    在这里我把我们常用的方法,属性,等全部整理了出来,大家不要嫌弃乱,静下心来,自己按照我的分隔一部分一部分的来,保证你对反射的学习,会事半功倍.当然有关于其方法我会继续补充,想了这么些就先写下来吧.





    ConstructorInfo.Invoke

    在.NET的Reflection中,ConstructorInfo和MethodInfo都是从MethodBase直接继承而来的.
    MethodInfo的Invoke函数使用很简单,就是直接
    MethodInfo.Invoke(object target,object[] parameters);

    但是ConstructorInfo的Invoke函数有一点不一样.

    同MethodInfo,ConstructorInfo的Invoke也有这种形式的重载...
    ConstructorInfo.Invoke(object target ,object[] parameters);
    这个Invoke用在调用父类的构造函数的时,也就是对已有的一个对象,去调用他的构造函数.即:
    class Father{
          public Father(...){}
    }
    class Son : Father{
          public Son(...):base(...){}
    }
    Son的构造函数的IL代码中,就会有相当于如下的函数的调用:
    ConstructorInfo.Invoke( this, parameters);
    //具体的代码可以参考AOP.NET中ProxyFactory的AopBaseHandler.cs中的Invoke函数.
    通过这种方式,完成子类Son对其父类Father的构造函数的调用.


    ConstructorInfo.Invoke还有一种形式:
    object ConstructorInfo.Invoke( object[] parameters);
    这个就是用来生成一个新的对象用的.即:
    object target = ConstructorInfo.Invoke(parameters);

    object target = new Son(parameters);
    是一样的...
    通过这个函数可以得到一个新的对象.和new是一样的效果.

    使用这个的时候可能要注意一下:P

    MethodInfo的Invoke函数使用很简单,就是直接
    MethodInfo.Invoke(object target,object[] parameters);

    但是ConstructorInfo的Invoke函数有一点不一样.

    同MethodInfo,ConstructorInfo的Invoke也有这种形式的重载...
    ConstructorInfo.Invoke(object target ,object[] parameters);
    这个Invoke用在调用父类的构造函数的时,也就是对已有的一个对象,去调用他的构造函数.即:
    class Father{
          public Father(...){}
    }
    class Son : Father{
          public Son(...):base(...){}
    }
    Son的构造函数的IL代码中,就会有相当于如下的函数的调用:
    ConstructorInfo.Invoke( this, parameters);
    //具体的代码可以参考AOP.NET中ProxyFactory的AopBaseHandler.cs中的Invoke函数.
    通过这种方式,完成子类Son对其父类Father的构造函数的调用.


    ConstructorInfo.Invoke还有一种形式:
    object ConstructorInfo.Invoke( object[] parameters);
    这个就是用来生成一个新的对象用的.即:
    object target = ConstructorInfo.Invoke(parameters);

    object target = new Son(parameters);
    是一样的...
    通过这个函数可以得到一个新的对象.和new是一样的效果.

    使用这个的时候可能要注意一下:P
  • 相关阅读:
    target runtime apache v6.0 not defined解决
    java.lang.AbstractMethodError: javax.servlet.jsp.JspFactory.getJspApplicationContext(Ljavax/servlet/ServletContext;)Ljavax/servlet/jsp/JspApplicationContext;
    The valid characters are defined in RFC 7230 and RFC 3986问题
    invalid END header解决方法
    You have more than one version of ‘org.apache.commons.logging.Log’ visible, which is not allowed问题解决
    Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986
    在eclipse中import java web项目时遇到的一些问题并将该项目通过tomcat发布
    java byte转string 涉及到字节流中有中文
    spring+mybatis框架搭建时遇到Mapped Statements collection does not contain value for...的错误
    试试看读一下Zepto源码
  • 原文地址:https://www.cnblogs.com/zwl12549/p/1245922.html
Copyright © 2011-2022 走看看