程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> 關於C# >> 反射學習系列1-反射入門

反射學習系列1-反射入門

編輯:關於C#

Reflection,中文翻譯為反射。這是.Net中獲取運行時類型信息的方式,.Net的應用程序由幾個部分:‘程序集(Assembly)’、‘模塊(Module)’、‘類型(class)’組成,而反射提供一種編程的方式,讓程序員可以在程序運行期獲得這幾個組成部分的相關信息,例如:Assembly類可以獲得正在運行的裝配件信息,也可以動態的加載裝配件,以及在裝配件中查找類型信息,並創建該類型的實例。Type類可以獲得對象的類型信息,此信息包含對象的所有要素:方法、構造器、屬性等等,通過Type類可以得到這些要素的信息,並且調用之。MethodInfo包含方法的信息,通過這個類可以得到方法的名稱、參數、返回值等,並且可以調用之。諸如此類,還有FieldInfo、EventInfo等等,這些類都包含在System.Reflection命名空間下。

一、Type類於獲取類型信息

System.Type 類對於反射起著核心的作用。當反射請求加載的類型時,公共語言運行庫將為它創建一個 Type。您可以使用 Type 對象的方法、字段、屬性和嵌套類來查找有關該類型的所有信息。

大家運行一下下面的代碼根據結果分析一下就能比較清楚的理解Type了

獲取類型信息

namespace ConsoleApplication2
{
  class Program
  {
    static void Main(string[] args)
    {
      MyClass m = new MyClass();
      Type type = m.GetType();
      Console.WriteLine("類型名:" + type.Name);
      Console.WriteLine("類全名:"+type.FullName);
      Console.WriteLine("命名空間名:"+type.Namespace);
      Console.WriteLine("程序集名:"+type.Assembly);
      Console.WriteLine("模塊名:"+type.Module);
      Console.WriteLine("基類名:"+type.BaseType);
      Console.WriteLine("是否類:"+type.IsClass);
      Console.WriteLine("類的公共成員:");
      MemberInfo[] memberInfos = type.GetMembers();//得到所有公共成員
      foreach (var item in memberInfos)
      {
        Console.WriteLine("{0}:{1}",item.MemberType,item);
      }
    }

  }
  class MyClass
  {
    public string m;
    public void test()
    { }
    public int MyProperty { get; set; }

  }
}

二、獲取程序集元數據

Assembly類定義了一個程序集,它是一個可重用、無版本沖突並且可自我描述的公共語言運行庫應用程序構造塊。因為程序集中是使用元數據進行自我描述的,所以我們就能通過其元數據得到程序集內部的構成。結合Assembly和反射能夠獲取程序集的元數據,但是首先要將程序集裝入內存中。可以使用Assembly類的多種靜態Load方法加載程序集。

下面的程序顯示程序集的信息

public static void Main()
    {
      //獲取當前執行代碼的程序集
      Assembly assem = Assembly.GetExecutingAssembly();

      Console.WriteLine("程序集全名:"+assem.FullName);
      Console.WriteLine("程序集的版本:"+assem.GetName().Version);
      Console.WriteLine("程序集初始位置:"+assem.CodeBase);
      Console.WriteLine("程序集位置:"+assem.Location);
      Console.WriteLine("程序集入口:"+assem.EntryPoint);

      Type[] types = assem.GetTypes();
      Console.WriteLine("程序集下包含的類型:");
      foreach (var item in types)
      {
        Console.WriteLine("類:"+item.Name);
      }

    }

三、動態加載類型

早綁定是在編譯時綁定對象類型,而晚綁定是在運行時才綁定對象的類型。利用反射可以實現晚綁定,即動態加載類型,並調用他們的方法,下邊是MSDN中的一個例子,詳細的解釋信息見注釋

動態加載類型

namespace ConsoleApplication2
{
  public class Example
  {
    private int factor;
    public Example(int f)
    {
      factor = f;
    }

    public int SampleMethod(int x)
    {
      Console.WriteLine("\nExample.SampleMethod({0}) executes.", x);
      return x * factor;
    }

    public static void Main()
    {
      //獲取當前執行代碼的程序集
      Assembly assem = Assembly.GetExecutingAssembly();

      Console.WriteLine("Assembly Full Name:");
      Console.WriteLine(assem.FullName);

      // The AssemblyName type can be used to parse the full name.
      AssemblyName assemName = assem.GetName();
      Console.WriteLine("\nName: {0}", assemName.Name);
      Console.WriteLine("Version: {0}.{1}",
        assemName.Version.Major, assemName.Version.Minor);
      Console.WriteLine("\nAssembly CodeBase:");
      Console.WriteLine(assem.CodeBase);
      // 從程序集眾創建一個Example實例並且用object類型的引用o指向它,同時調用一個輸入參數的構造函數
      Object o = assem.CreateInstance("ConsoleApplication2.Example", false,
        BindingFlags.ExactBinding,
        null, new Object[] { 2 }, null, null);

      //構造Example類的一個晚綁定的方法SampleMethod
      MethodInfo m = assem.GetType("ConsoleApplication2.Example").GetMethod("SampleMethod");
      //調用剛才實例化好的Example對象o中的SampleMethod方法,傳入的參數為42
      Object ret = m.Invoke(o, new Object[] { 42 });
      Console.WriteLine("SampleMethod returned {0}.", ret);

      Console.WriteLine("\nAssembly entry point:");
      Console.WriteLine(assem.EntryPoint);
    }
  }

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved