(C#)利用反射動態呼叫類成員

ljm0211發表於2012-07-02
使用反射動態呼叫類成員,需要Type類的一個方法:InvokeMember。對該方法的宣告如下(摘抄於MSDN):


public object InvokeMember(

   string name,

   BindingFlags invokeAttr,

   Binder binder,

   object target,

   object[] args

);

引數

name

String,它包含要呼叫的建構函式、方法、屬性或欄位成員的名稱。

- 或 -

空字串 (""),表示呼叫預設成員。

invokeAttr

一個位遮蔽,由一個或多個指定搜尋執行方式的 BindingFlags 組成。訪問可以是 BindingFlags 之一,如 Public、NonPublic、Private、InvokeMethod 和 GetField 等。不需要指定查詢型別。如果省略查詢型別,則將應用 BindingFlags.Public | BindingFlags.Instance。

binder

一個 Binder 物件,該物件定義一組屬性並啟用繫結,而繫結可能涉及選擇過載方法、強制引數型別和透過反射呼叫成員。

- 或 -

若為空引用(Visual Basic 中為 Nothing),則使用 DefaultBinder。

target

要在其上呼叫指定成員的 Object。

args

包含傳遞給要呼叫的成員的引數的陣列。

返回值

表示被呼叫成員的返回值的 Object。

   備註:

下列 BindingFlags 篩選標誌可用於定義包含在搜尋中的成員:

為了獲取返回值,必須指定 BindingFlags.Instance 或 BindingFlags.Static。

指定 BindingFlags.Public 可在搜尋中包含公共成員。

指定 BindingFlags.NonPublic 可在搜尋中包含非公共成員(即私有成員和受保護的成員)。

指定 BindingFlags.FlattenHierarchy 可包含層次結構上的靜態成員。

下列 BindingFlags 修飾符標誌可用於更改搜尋的執行方式:

BindingFlags.IgnoreCase,表示忽略 name 的大小寫。

BindingFlags.DeclaredOnly,僅搜尋 Type 上宣告的成員,而不搜尋被簡單繼承的成員。

可以使用下列 BindingFlags 呼叫標誌表示要對成員採取的操作:

CreateInstance,表示呼叫建構函式。忽略 name。對其他呼叫標誌無效。

InvokeMethod,表示呼叫方法,而不呼叫建構函式或型別初始值設定項。對 SetField 或 SetProperty 無效。

GetField,表示獲取欄位值。對 SetField 無效。

SetField,表示設定欄位值。對 GetField 無效。

GetProperty,表示獲取屬性。對 SetProperty 無效。

SetProperty 表示設定屬性。對 GetProperty 無效。

下面透過例題對該方法進行簡單應用(我一直以為,要讓例題起到更容易理解文字的意義和作用,撰寫的例題越簡單越直觀越好。)

using System;

using System.Reflection;

namespace ConsoleApplication9

{

    class Love

    {

        public int field1;

        private string _name;

        public Love()

        {

        }

        public string Name

        {

            get

            {

                return _name;

            }

            set

            {

                _name=value;

            }

        }

        public int GetInt(int a)

        {

            return a;

        }

        public void Display(string str)

{

            Console.WriteLine(str);

        }

    }

    ///

    /// Class1 的摘要說明。

    ///

    class Class1

    {

        ///

        /// 應用程式的主入口點。

        ///

        [STAThread]

        static void Main(string[] args)

        {

            //

            // TODO: 在此處新增程式碼以啟動應用程式

            //

            Love love = new Love();

            Type type = love.GetType();

            Object bj = type.InvokeMember(null,

                BindingFlags.DeclaredOnly |

                BindingFlags.Public | BindingFlags.NonPublic |

                BindingFlags.Instance | BindingFlags.CreateInstance, null, null, args);

//呼叫沒有返回值的方法

            type.InvokeMember("Display",BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance , null , obj , new object[]{"aldfjdlf"});

            //呼叫有返回值的方法

            int i = (int)type.InvokeMember("GetInt",BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance,null,obj,new object[]{1});

            Console.WriteLine(i);

            //設定屬性值

            type.InvokeMember("Name",BindingFlags.SetProperty,null,obj,new string[]{"abc"});

            //獲取屬性值

            string str=(string)type.InvokeMember("Name",BindingFlags.GetProperty,null,obj,null);

            Console.WriteLine(str);

            //設定欄位值

            type.InvokeMember("field1",BindingFlags.SetField,null,obj,new object[]{444});

            //獲取欄位值

            int f=(int)type.InvokeMember("field1",BindingFlags.GetField,null,obj,null);

            Console.WriteLine(f);

            Console.ReadLine();

        }

    }

}

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/11411056/viewspace-734393/,如需轉載,請註明出處,否則將追究法律責任。

相關文章