萬盛學電腦網

 萬盛學電腦網 >> 網絡編程 >> 編程語言綜合 >> 關於C#基礎知識回顧--反射

關於C#基礎知識回顧--反射

其實說白了,反射就是能知道我們未知類型的類型信息這麼一個東西.沒什麼神秘可講!反射的核心是System.Type。System.Type包含了很多屬性和方法,使用這些屬性和方法可以在運行時得到類型信息  

反射(reflection)是一種允許用戶獲得類型信息的C#特性。術語“反射”源自於它的工作方式:
Type對象映射它所代表的底層對象。對Type對象進行查詢可以獲得(反射)與類型相關的信息。反射是一種
功能強大的機制,它允許學習和使用只在運行時才能知道的類型功能。

這些是官方定義,其實說白了,反射就是能知道我們未知類型的類型信息這麼一個東西.沒什麼神秘可講!
反射的核心是System.Type。System.Type包含了很多屬性和方法,使用這些屬性和方法可以在運行時得到類型信息。
一旦得到類型信息,就可以調用其構造函數、方法和屬性。因此,反射允許使用編譯時不可用的代
碼。因為反射涉及內容太多,我們主要學習常用的反射技術。

一、獲取方法的相關信息
一旦有了Type對象,就可以使用GetMethods()方法來獲取此類型支持的方法的列表。它的一種形式為:
MethodInfo[] GetMethods()
MethodInfo對象描述了主調類型所支持的方法,因此可以通過它的Name屬性獲得方法的名稱。同時它還有兩個重
要的方法,ReturnType和GetParameters()。

只讀屬性ReturnType為一個Type類型的對象,它為用戶提供方法的返回類型信息。
GetParameters()返回一個方法的參數列表,它的基本形式為:
ParameterInfo[] GetParameters();
參數信息保存在ParameterInfo對象中。ParameterInfo類定義了大量描述參數信息的屬性和方法。
其中常用屬性是Name和ParameterType,這兩個屬性我就不介紹了,從字面上應該可以理解了。
好了,不說了,講了這麼多概念想必大家都不耐煩了。下面我們先看代碼示例,估計你看了以後,再結合上面的
概念講解,你一定會說:哦,原來如此!!!

復制代碼 代碼如下:
class MyClass
    {
        int x;
        int y;
        public MyClass(int i, int j)
        {
            x = i;
            y = j;
        }
        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)
        {
            x = a;
            y = b;
        }
        public void Set(double a, double b)
        {
            x = (int)a;
            y = (int)b;
        }
        public void Show()
        {
            Console.WriteLine("x:{0},y:{1}", x, y);
        }
    }


運行結果:



請注意,除了MyClass定義的方法外,object定義的方法也會被顯示。這是因為C#所有的類都繼承於object。
另外,類型名稱(如Int32)采用的是.net結構的名稱。

二、GetMethods()的另外一種形式
這種形式中可以指定各種標記,以此篩選出想要獲取的方法,它的基本形式:
MethodInfo[] GetMethods(BindingFlags flags)
這種形式只獲得與所指定的條件相匹配的方法,BindingFlages 是一個枚舉,相關知識請參考:
msdn上BindingFlags 枚舉

可以使用OR運算符把兩個或者更多的標記連接在一起。實際上,括號中至少應包含Instance(或Static)
與Public(或NotPublic)標記,否則將不會獲得任何方法。

GetMethods()方法的BindingFlages形式的一個主要用途在於,它可以只獲得某個類自身定義的方法而不
獲得它從基類繼承的方法,這對於object尤其有用。
例如用下列形式來替換前面程序中的GetMethods()語句:

復制代碼 代碼如下:
MethodInfo[] mi = t.GetMethods(BindingFlags.DeclaredOnly |
BindingFlags.Instance |
BindingFlags.Public);


進行上述更改後,程序的輸出結果為:



可以看出,這裡只顯示了MyClass顯示定義的方法。

使用反射調用方法:
一旦知道一個類型所支持的方法,就可以對方法進行調用。調用時,需使用包含在
MethodInfo中的Invoke()方法。調用形式:
object Invoke(object ob, object[] args)
 
這裡ob是一個對象引用,將調用它所指向的對象上的方法。對於靜態方法,ob必須為null。

所有需要傳遞給方法的參數都必須在args數組中指定。如果方法不需要參數,則args必須為null。

另外,數組args的元素數量參數必須等於參數的數量。Invoke()方法返回被調用方法的返回值。

要調用某個方法,只需在一個MethodInfo實例上調用Invoke(),該實例通過調用
GetMethods()

方法獲得。請看事例:

復制代碼 代碼如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
namespace Reflection
{
    class Program
    {
        static void Main(string[] args)
        {
           // Demo1();
            InvokeMethDemo();
            Console.ReadKey();
        }

        static void InvokeMethDemo()
        {
            //獲得MyClass的類型隊形
            Type t = typeof(MyClass);
            MyClass reflectOb = new MyClass(10, 20);
            Console.WriteLine("類名:{0}", t.Name);
            Console.WriteLine("本類所提供的方法有:");
    &
copyright © 萬盛學電腦網 all rights reserved