天天看點

反射(轉載)

在網上查找了不少的資料,可以說大同小異,概念性的東西網上一搜一堆,

今天把反射的東西整理了一下,供大家使用,我保證我這裡是最全面的東西,當然也是基礎的東西,

在學好了這一切的基礎上,大家可以學習反射的具體插件等應用,老鳥就不用看了.

首先我們建立一個類庫,将它生成為helloworld.dll,

反射(轉載)

using system;

反射(轉載)
反射(轉載)

 namespace webtest

反射(轉載)

 {

反射(轉載)
反射(轉載)

    public interface interface1

反射(轉載)

     {

反射(轉載)

          int add();

反射(轉載)
反射(轉載)

     }

反射(轉載)

     public class reflecttest:interface1

反射(轉載)

     ...

反射(轉載)

}

然後,建立再建立一個項目引入該helloworld.dll,

反射(轉載)
反射(轉載)
反射(轉載)

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();

反射(轉載)

    }   

反射(轉載)

在這裡我把我們常用的方法,屬性,等全部整理了出來,大家不要嫌棄亂,靜下心來,自己按照我的分隔一部分一部分的來,保證你對反射的學習,會事半功倍.當然有關于其方法我會繼續補充,想了這麼些就先寫下來吧.

在.net的reflection中,constructorinfo和methodinfo都是從methodbase直接繼承而來的.

methodinfo的invoke函數使用很簡單,就是直接

methodinfo.invoke(object target,object[]

parameters);

但是constructorinfo的invoke函數有一點不一樣.

同methodinfo,constructorinfo的invoke也有這種形式的重載...

constructorinfo.invoke(object target ,object[]

這個invoke用在調用父類的構造函數的時,也就是對已有的一個對象,去調用他的構造函數.即:

class father{

public father(...){}

class son :

father{

      public

son(...):base(...){}

son的構造函數的il代碼中,就會有相當于如下的函數的調用:

constructorinfo.invoke( this,

//具體的代碼可以參考aop.net中proxyfactory的aopbasehandler.cs中的invoke函數.

通過這種方式,完成子類son對其父類father的構造函數的調用.

constructorinfo.invoke還有一種形式:

object constructorinfo.invoke( object[]

這個就是用來生成一個新的對象用的.即:

object

target = constructorinfo.invoke(parameters);

object target = new

son(parameters);

是一樣的...

通過這個函數可以得到一個新的對象.和new是一樣的效果.

使用這個的時候可能要注意一下:p