文章出處

從程序集獲得類型

  先說點題外話,現在技術真的發展太快了。我這邊還很多東西半生不熟

呢,那邊又出現了好多有趣的新東西讓你眼紅不已。學還是不學這還真是

個問題。Node.js 、bootstrap,我最近剛發現的新技術,其實他們已經

存在很久了,只是沒有接觸過而已。昨天晚上看Node.js一下子看到兩點

多,感覺真是太有意思了^,有興趣的可以去看看,大家多交流交流.

  好了不廢話了,在前面的示例中,幾乎全部的MyClass信息都是通過反射得到的,但是有一個例外:

MyClass類型本身。雖然前面的示例可以動態確定MyClass的信息,但它們仍基于以下事實:事先知道

類型名MyClass,并且在typeof語句中使用它創建一個Type對象。盡管這種方式可能在很多環境中都有

用,但是要發揮反射的全部功能,就必須能通過分析其他程序集的內容動態的獲取可用的類型。

  程序集提供了它包含的類和結構的信息。借助反射應用程序接口,可以加載程序集,獲取它的相

關信息并創建其公共可用類型的實例。通過使用這種機制,程序能夠搜素其環境,利用那些潛在的功能而

無需在編譯期間顯示的定義他們。由于類型的全部信息都可以被發現,因此不存在反射應用的內在限制。

為了獲取程序集的相關信息,首先需要創建一個Assembly對象。Assembly類并沒有定義公有的

構造函數,它的對象實例是通過類的一個方法獲得的。這里使用的LoadFrom()方法可以加載由文件名

指定的程序集,其形式如下:

  static Assembly LoadFrom(string fileName)

一旦獲得了Assembly類型的對象,就可以通過調用該對象的GetType()來得到它所定義的類型

。基本形式如下:

  Type[] GetTypes()

  此方法返回一個數組,它包含了程序集的類型。

  為了說明如何獲取程序集的類型,我們需要在解決方案中添加一個類庫,類庫名字為MyClasses,

在類庫中添加三個類:MyClass、AnotherClass、Demo。代碼如下:

程序集MyClasses代碼

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyClasses
{
    public class MyClass
    {
        int x;
        int y;

        public MyClass(int i)
        {
            Console.WriteLine("一個參數的構造函數:");
            x = y = i;
        }
        public MyClass(int i, int j)
        {
            Console.WriteLine("兩個參數構造函數:");
            x = i;
            y = j;

            Show();
        }

        public int Sum()
        {
            return x + y;
        }

        public bool IsBetween(int i)
        {
            if (x < i && i < y)
                return true;
            else
                return false;
        }

        public void Set(int a, int b)
        {
            Console.Write("函數:Set(int a, int b)");
            x = a;
            y = b;

            Show();
        }

        public void Set(double a, double b)
        {
            Console.Write("函數:Set(double a, double b)");

            x = (int)a;
            y = (int)b;

            Show();
        }

        public void Show()
        {
            Console.WriteLine("x:{0},y:{1}", x, y);
        }

    }

    public class AnotherClass
    {
        string msg;

        public AnotherClass(string msg)
        {
            this.msg = msg;
        }

        public void show() {
            Console.WriteLine(msg);
        }
    }
    public class Demo
    {
        public void test()
        {
            Console.WriteLine("我是打醬油的!!");
        }
    }
}

 

使用反射代碼:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
namespace Reflection
{
    class Program
    {
        static void Main(string[] args)
        {
           
            ReflectAssemblyDemo();
            Console.ReadKey();
        }


        static void ReflectAssemblyDemo()
        {
            int val;

            Assembly asm = Assembly.LoadFrom("MyClasses.dll");

            Type[] allTypes = asm.GetTypes();

            foreach (Type type in allTypes)
            {
                Console.WriteLine("程序集中找到類:" + type.Name);
            }
            Console.WriteLine();

            //使用第一個類
            Type t = allTypes[0];

            Console.WriteLine("使用類:" + t.Name);

            //獲得構造函數
            ConstructorInfo[] ci = t.GetConstructors();

            //顯示此類中的構造函數
            Console.WriteLine("此類中的構造函數有:");

            foreach (ConstructorInfo c in ci)
            {
                Console.Write("  " + t.Name + " (");

                ParameterInfo[] pi = c.GetParameters();

                for (int i = 0; i < pi.Length; i++)
                {
                    Console.Write(pi[i].ParameterType.Name + " " + pi[i].Name);

                    if (i + 1 < pi.Length) Console.Write(",");
                }

                Console.WriteLine(")");
            }

            //獲取匹配的構造函數

            int x;

            for (x = 0; x < ci.Length; x++)
            {
                ParameterInfo[] pi = ci[x].GetParameters();
                if (pi.Length == 2) break;
            }

            if (ci.Length == x)
            {
                Console.WriteLine("沒有匹配的構造函數");
                return;
            }
            else
            {
                object[] consargs = new object[2];

                consargs[0] = 10;
                consargs[1] = 20;

                object reflectOb = ci[x].Invoke(consargs);

                Console.WriteLine("通過reflectOb調用方法");

                Console.WriteLine();

                MethodInfo[] mi = t.GetMethods();

                foreach (MethodInfo m in mi)
                {
                    //獲得方法參數

                    ParameterInfo[] pi = m.GetParameters();

                    if (m.Name.CompareTo("Set") == 0 && pi[0].ParameterType == typeof(int))
                    {
                        object[] args = new object[2];

                        args[0] = 9;
                        args[1] = 18;

                        m.Invoke(reflectOb, args);
                    }
                    else if (m.Name.CompareTo("Set") == 0 && pi[0].ParameterType == typeof(double))
                    {
                        object[] args = new object[2];

                        args[0] = 1.25;
                        args[1] = 7.5;

                        m.Invoke(reflectOb, args);
                    }
                    else if (m.Name.CompareTo("Sum") == 0)
                    {
                        val = (int)m.Invoke(reflectOb, null);

                        Console.WriteLine("Sum is {0}", val);
                    }
                    else if (m.Name.CompareTo("IsBetween") == 0)
                    {
                        object[] args = new object[1];

                        args[0] = 13;

                        if ((bool)m.Invoke(reflectOb, args))
                        {
                            Console.WriteLine("13 is between x and y");
                        }

                    }
                    else if (m.Name.CompareTo("Show") == 0)
                    {
                        m.Invoke(reflectOb, null);
                    }
                }
            }
        }
    }
}

運行結果:

 


  自此,反射部分基本內容寫完了.希望對大家有所幫助.現在正在進行WPF開發,我會把在項目開發中遇到的問題與解決方案及時與您分享,希望您能繼續關注.

  最后,如果本文對您有所幫助,請點推薦,謝謝!

 


文章列表


不含病毒。www.avast.com
全站熱搜
創作者介紹
創作者 大師兄 的頭像
大師兄

IT工程師數位筆記本

大師兄 發表在 痞客邦 留言(0) 人氣()