C# 反射之調用方法談


反射的定義

反射提供了描述程序集、模塊和類型的對象(Type 類型)。 可以使用反射動態創建類型的實例,將類型綁定到現有對象,或從現有對象獲取類型並調用其方法或訪問其字段和屬性。 如果代碼中使用了特性,可以利用反射來訪問它們。------摘自MSDN

 

自我理解

看到反射二字,自然而然的會想到,小時候拿着一面鏡子,反射陽光玩。其實

反射就好比一面鏡子,通過它我們能在不顯示引用程序集的情況下,一窺程序集內的“風景”。

 

利用好反射這把利器,我們在開發中就能體會到荀老夫子所言的,君子性非異也,善假於物也

本文主要包括以下四節:

通過反射調用類的構造函數(有參/無參)

通過反射調用類的靜態方法(有參/無參)

通過反射調用類的非靜態方法(有參/無參)

通過反射調用類的含有ref參數的方法

代碼示例:

 1 namespace TestDLL
 2 {
 3     using System.Linq;
 4 
 5     public class TestClass
 6     {
 7         private int _priValue;
 8 
 9         //無參構造函數
10         public TestClass()
11         {
12             this._priValue = 9;
13         }
14 
15         //有參構造函數
16         public TestClass(int i)
17         {
18             this._priValue = i;
19         }
20 
21         //無參方法
22         public int Add()
23         {
24             return ++this._priValue;
25         }
26 
27         //ref參數的方法
28         public void Exchange(ref int a, ref int b)
29         {
30             int temp = b;
31             b = a;
32             a = temp;
33         }
34 
35         // 靜態有參方法 
36         public static string SayHi(string name)
37         {
38             return "Hi~ " + name;
39         }
40 
41         public static int AddValue(int[] objsInts)
42         {
43             int temp = 0;
44             if (objsInts != null)
45             {
46                 temp += objsInts.Sum();
47             }
48             return temp;
49         }
50     }
51 }
View Code

通過反射調用代碼示例:

    static void Main(string[] args)
        {
            //加載程序集(dll文件地址),使用Assembly類 
            Assembly testDll = Assembly.LoadFile(Environment.CurrentDirectory + "\\TestDLL.dll");

            //獲取類型,參數(名稱空間+類)
            Type testClass = testDll.GetType("TestDLL.TestClass");

            //創建實例
            var instance = testDll.CreateInstance("TestDLL.TestClass");

            //調用無參構造函數
            ConstructorInfo noParamConstructor = testClass.GetConstructor(Type.EmptyTypes);
            object testClassObject = noParamConstructor.Invoke(new object[] { });

            //調用有參構造函數
            ConstructorInfo paramConstructor = testClass.GetConstructor(new Type[] { Type.GetType("System.Int32") });
            object testClassObject2 = paramConstructor.Invoke(new object[] { 2 });

            #region 調用非靜態方法
            MethodInfo addMethod = testClass.GetMethod("Add");
            object addValue = addMethod.Invoke(instance, new object[] { });
            #endregion

            #region 調用靜態有參方法
            MethodInfo sayHiMethod = testClass.GetMethod("SayHi");
            object sayHi = sayHiMethod.Invoke(null, new object[] { "jason" });
            #endregion

            #region 調用含有ref參數的方法
            MethodInfo exchange = testClass.GetMethod("Exchange");
            var objs = new object[2];
            objs[0] = 5;
            objs[1] = 6;
            Console.WriteLine("objs[0]={0}\nobjs[1]={1}", objs[0], objs[1]);
            object retValue = exchange.Invoke(instance, objs); #endregion

            #region 調用參數為數組的方法
            MethodInfo addValueInfo = testClass.GetMethod("AddValue");
            var ints = new int[] {1, 2, 3, 4, 5};
            object obj = addValueInfo.Invoke(null, new object[] {ints});
            #endregion

            Console.WriteLine("MethodInfo.Invoke() Example\n");
            Console.WriteLine("TestClass.Add() returned: {0}", addValue);
            Console.WriteLine("TestClass.SayHi() returned:{0}", sayHi);
            Console.WriteLine("TestClass.Exchange(ref int a,ref int b) returned:{0}", retValue);
            Console.WriteLine("objs[0]={0}\nobjs[1]={1}", objs[0], objs[1]);

            Console.WriteLine("AddValue(int[] objsInts) result:{0}", obj);
        }

 在此對代碼中紅色加粗的方法做注(摘自MSDN):

MethodBase.Invoke 方法 (Object, Object[])

使用指定的參數調用當前實例所表示的方法或構造函數。

語法

public Object Invoke(

Object obj,

Object[] parameters

)

 

參數

obj

類型:System.Object

對其調用方法或構造函數的對象。 如果方法是靜態的,則忽略此參數。 如果構造函數是靜態的,則此參數必須為 null 或定義該構造函數的類的實例。

若要使用其 MethodInfo 對象來調用靜態方法,請將 null 傳遞給 obj。

parameters

類型:System.Object[]

調用的方法或構造函數的參數列表。 這是一個對象數組,這些對象與要調用的方法或構造函數的參數具有相同的數量、順序和類型。 如果沒有任何參數,則 parameters 應為 null。

如果此實例所表示的方法或構造函數采用 ref 參數(在 Visual Basic 中為 ByRef),使用此函數調用該方法或構造函數時,該參數不需要任何特殊屬性。 如果此數組中的對象未用值來顯式初始化,則該對象將包含該對象類型的默認值。 對於引用類型的元素,該值為 null。 對於值類型的元素,該值為 0、0.0 或 false,具體取決於特定的元素類型。

返回值

類型:System.Object

一個對象,包含被調用方法的返回值,如果調用的是構造函數,則為 null。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM