日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

.NET 反射原理及其运用

發(fā)布時(shí)間:2024/1/1 asp.net 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 .NET 反射原理及其运用 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一.何謂反射

反射:是.net framework提供的一個(gè)訪問metadata的幫助類庫,可以獲取信息并且使用
動態(tài)是反射中的最大優(yōu)點(diǎn)。

二:反射如何使用

#region 反射的加載方式 獲取當(dāng)前路徑下面的dl或者exe,不帶后綴(MyReflection.exe 是編譯后生成的exe執(zhí)行文件),從Exe所在的路徑進(jìn)行查找 Assembly assembly = Assembly.Load(@"MyReflection"); //獲取完整路徑下面的dl或者exe,要加后綴 Assembly assemblyFrom = Assembly.LoadFrom(@"D:\MyReflection\bin\Debug\MyReflection.exe"); //獲取完整路徑下面的dl或者exe,要加后綴 Assembly assemblyFile = Assembly.LoadFile(@"D:\MyReflection\bin\Debug\MyReflection.exe"); foreach (var item in assembly.GetModules()) {//Modules當(dāng)前的exe或者dll的名字(MyReflection.exe)Console.WriteLine(item.Name); } //當(dāng)前所包含的實(shí)體類(IDBHelper,SqlServerHelper,Program) foreach (var item in assembly.GetTypes()) {foreach(var method in item.GetMethods()){Console.WriteLine(method.Name); }Console.WriteLine(item.Name); }foreach (var item in assembly.GetCustomAttributes()) {Console.WriteLine(item.ToString()); } //獲取到有多個(gè)構(gòu)造函數(shù) foreach (var ctor in type.GetConstructors()) { Console.WriteLine(ctor.GetParameters()); //獲取構(gòu)造函數(shù)里面的參數(shù) foreach (var item in ctor.GetParameters()) { Console.WriteLine(item.ParameterType); } } #endregion

三.反射的應(yīng)用

(一)可以利用反射 創(chuàng)建一個(gè)類的實(shí)例,并調(diào)用他的方法

1.創(chuàng)建步驟

例如:

(1).獲取類型:
Type dbhelperType = assembly.GetTyp(“Ruanmou.DB.MySql.MySqlHelper”);//== 獲取所需創(chuàng)建類型的類型信息,傳參數(shù)必須傳遞完整類名,從命名空間開始==
(2).創(chuàng)建類型對應(yīng)的實(shí)例對象
//用Activator.CreateInstance(類型參數(shù))創(chuàng)建所需類型的實(shí)例對象
object oDBHelper = Activator.CreateInstance(dbhelperType);
(3).轉(zhuǎn)換并調(diào)用方法:
用其對應(yīng)的接口進(jìn)行轉(zhuǎn)換
IDBHelper idbhelper = oDBHelper as IDBHelper;
idbhelper.Query();

2.具體應(yīng)用

在寫程序的時(shí)候,需要靈活運(yùn)用類的時(shí)候,可以先在配置文件中,將需要的類型配置進(jìn)去,然后在程序中根據(jù)配置文件靈活的創(chuàng)建所需要的類型對象:舉例,程序有可能需要多種數(shù)據(jù)庫,MySql 和SqlServer,寫底層數(shù)據(jù)庫連接的時(shí)候并不知道上層需要哪個(gè),于是可以利用在配置文件中的連接字符串中配置Provider的dll,用反射的方式在底層創(chuàng)建連接字符串的時(shí)候,根據(jù)上層傳入的連接字符串來靈活創(chuàng)建底層連接Connection.

/// <summary> /// 反射得到一個(gè)對象/// </summary>public class SimpleFactory{//讀取配置文件AppSetting里面的key// <appSettings>// <add key = "DbConfig" value="MyReflection,MyReflection.MySqlServerHelper"/>//</appSettings>private static string ConfigStr = ConfigurationManager.AppSettings["DbConfig"];private static string DllName = ConfigStr.Split(',')[0]; //命名空間private static string TypeName = ConfigStr.Split(',')[1]; //類型要完整命名空間+類名public static T CreateInstance<T>(){Assembly assembly = Assembly.Load(DllName);Type type = assembly.GetType(TypeName);var objectInstance = Activator.CreateInstance(type);return (T)objectInstance; //要強(qiáng)制轉(zhuǎn)換一下,因?yàn)闋可娴骄幾g性語言和運(yùn)行時(shí)語言}}

(二):反射調(diào)用多構(gòu)造函數(shù),調(diào)用私有構(gòu)造函數(shù)(破壞單例),調(diào)用泛型類

首先創(chuàng)建一個(gè)實(shí)體類,包含有參無參構(gòu)造函數(shù),然后有參無參的方法,如下:

/// <summary>/// sqlServer/// </summary>public class SqlServerHelper : IDBHelper{//private SqlServerHelper()//{// Console.WriteLine("私有構(gòu)造函數(shù)");//}//無參構(gòu)造函數(shù)public SqlServerHelper(){Console.WriteLine("公有無參構(gòu)造函數(shù)");}//傳入一個(gè)int型參數(shù)的構(gòu)造函數(shù)public SqlServerHelper(int iParam){Console.WriteLine($"int的構(gòu)造函數(shù)--{iParam}");}//傳入一個(gè)string型參數(shù)的構(gòu)造函數(shù)public SqlServerHelper(string sParam){Console.WriteLine($"string的構(gòu)造函數(shù)--{sParam}");}//傳入兩個(gè)參數(shù)的構(gòu)造函數(shù)public SqlServerHelper(int iParam, string sParam){Console.WriteLine($"int和string的構(gòu)造函數(shù)--int={iParam} ;string={sParam}");}//類內(nèi)部的無參方法public void Show(){Console.WriteLine("Show");}//類內(nèi)部的Show1的無參方法public void Show1(){Console.WriteLine("Show1的無參方法");}//類內(nèi)部的Show1的int重載方法public void Show1(int iParam){Console.WriteLine($"Show1的int重載--{iParam}");}//類內(nèi)部的Show1的兩參重載方法public void Show1(int iParam, string sParam){Console.WriteLine($"Show1兩參數(shù) iparam={iParam};sParam={sParam}");} }

1.調(diào)用上面例子類中的 有參 或者 無參構(gòu)造函數(shù)

Assembly assembly = Assembly.Load("MyReflection"); //獲取當(dāng)前路徑下面的dl或者exe,不帶后綴 Type dbHelperType = assembly.GetType("MyReflection.SqlServerHelper"); //傳完整名稱獲類型(命名空間+類名) //調(diào)用多個(gè)構(gòu)造函數(shù)(有參,無參) var obSqlServerHelper = Activator.CreateInstance(dbHelperType); //無參的構(gòu)造函數(shù) Activator.CreateInstance(dbHelperType, new object[] { 11 }); //int的構(gòu)造函數(shù) Activator.CreateInstance(dbHelperType, new object[] { "testbywss" }); //調(diào)用string的構(gòu)造函數(shù) Activator.CreateInstance(dbHelperType, new object[] { 123, "testbywss" }); //調(diào)用string的構(gòu)造函數(shù)

2. 調(diào)用類的私有構(gòu)造函數(shù)

//私有構(gòu)造函數(shù)Type singletonType = assembly.GetType("MyReflection.Singleton"); //傳入完整名稱獲取類型(命名空間+類名)var object1 = Activator.CreateInstance(singletonType, true); //設(shè)置成true能調(diào)用私有/公布的構(gòu)造函數(shù),如果不設(shè)置則只能調(diào)用公有構(gòu)造函數(shù)

3.不必強(qiáng)制類型轉(zhuǎn)換,調(diào)用 普通方法,靜態(tài)方法,重載方法:

在利用了反射實(shí)例化對象之后,可以不需要強(qiáng)制類型轉(zhuǎn)換,直接調(diào)用其方法

Type dbhelperType = assembly.GetTyp(“Ruanmou.DB.SqlServer.SqlServerHelper ”);
object obSqlServerHelper = Activator.CreateInstance(dbhelperType);

(1)普通方法

Type 類型 的對象,有一個(gè)方法 GetMethods方法,可以獲取這個(gè)類型對象中所指定的方法,
如下:
MethodInfo methodInfo = dbhelperType.GetMethod(“Show”); //MethodInfo 類,用于描述方法
用獲取到指定方法的 MethodInfo 對象 來調(diào)用方法
methodInfo.Invoke(obSqlServerHelper, null); //第一個(gè)參數(shù):要調(diào)用方法的實(shí)例,普通方法必須實(shí)例化之后進(jìn)行調(diào)用,上面已經(jīng)用Activator.CreateInstance實(shí)例化了一個(gè)該Type的實(shí)例,這里將其傳入,第二個(gè)參數(shù):是方法需要的參數(shù),如果沒有則設(shè)置為null

(2) 靜態(tài)方法調(diào)用

MethodInfo staticMethodInfo = dbHelperType.GetMethod(“Show5”); //調(diào)用單個(gè)普通的實(shí)例方法
== staticMethodInfo.Invoke(null, new object[] { “靜態(tài)方法第一種調(diào)用方式” }); //第一個(gè)參數(shù):是應(yīng)用對象,如果是靜態(tài)可以不用寫;第二個(gè)參數(shù):是方法需要的參數(shù),如果沒有則設(shè)置為null ==
staticMethodInfo.Invoke(obSqlServerHelper, new object[] { “靜態(tài)方法第二種調(diào)用方式” });//重載方法調(diào)用

(3) 調(diào)用重載方法

重載方法
MethodInfo method2 = dbHelperType.GetMethod(“Show1”, new Type[] { }); //調(diào)用無參的函數(shù)
method2.Invoke(obSqlServerHelper, null);

MethodInfo method3 = dbHelperType.GetMethod(“Show1”, new Type[] { typeof(int) }); //int參數(shù)的方法
method3.Invoke(obSqlServerHelper, new object[] { 11 });

MethodInfo method4 = dbHelperType.GetMethod(“Show1”, new Type[] { typeof(int), typeof(string) }); //調(diào)用2個(gè)參數(shù)的方法,new Type[] { typeof(int), typeof(string) } 順序一定要跟調(diào)用的方法的參數(shù)順序保持一致
method4.Invoke(obSqlServerHelper, new object[] { 1111, “ddd” });

4:調(diào)用泛型

(1)首先要?jiǎng)?chuàng)建一個(gè)實(shí)體類如下:
#region 泛型類public class GenericClass<T, W, F>{public void Show(T t, W w, F f){Console.WriteLine($"t.type={t.GetType().Name};}");}}public class GenericMethod{public void Show<T, W, X>(T t, W w, X x){Console.WriteLine($"t.type={t.GetType().Name};");}}public class GenericDouble<T>{public void Show<W, X>(T t, W w, X x){Console.WriteLine($"t.type={t.GetType().Name};");}}#endregion
(2)調(diào)用泛型方法如下

//創(chuàng)建泛型
Assembly assembly = Assembly.Load(“MyReflection”); //獲取當(dāng)前路徑下面的dl或者exe,不帶后綴
== 創(chuàng)建泛型類,創(chuàng)建泛型類的時(shí)候,除了寫好類名,還要給占位符,以告訴系統(tǒng)這個(gè)類是一個(gè)泛型類,3個(gè)占位符,表示泛型類傳入三個(gè)類型參數(shù)。==
Type genericType = assembly.GetType("MyReflection.GenericClass3"); //3是泛型類需要的參數(shù)
== 在調(diào)用實(shí)例化之前,要先指定具體的泛型的類型==
Type typeGenericNew = genericType.MakeGenericType(typeof(int), typeof(int), typeof(int)); //需要指定泛型類的類型
GenericClass<int, int, int> oGeneric = (GenericClass<int, int, int>)Activator.CreateInstance(typeGenericNew);
oGeneric.Show(1, 30, 60);

Type genericType1 = assembly.GetType(“MyReflection.GenericMethod”); //普通的類
var genericMethod = Activator.CreateInstance(genericType1) as GenericMethod;
genericMethod.Show<int, string, double>(1, “1”, 2);

5:調(diào)用私有方法

//私有方法 //調(diào)用私有方法,有參數(shù) MethodInfo method5 = dbHelperType.GetMethod("Show5", BindingFlags.NonPublic | BindingFlags.Instance); method5.Invoke(obSqlServerHelper, new object[] { 5.0 });//私有方法,無參數(shù) MethodInfo method6 = dbHelperType.GetMethod("Show6", BindingFlags.NonPublic | BindingFlags.Instance); method6.Invoke(obSqlServerHelper, null);

6:調(diào)用普通方法的泛型方法

//類的泛型方法調(diào)用 Type genericMethodType = assembly.GetType("MyReflection.GenericMethod"); var objectGeneric = Activator.CreateInstance(genericMethodType); MethodInfo genericMethod = genericMethodType.GetMethod("Show"); //這一步是調(diào)用泛型方法的關(guān)鍵,給泛型方法的參數(shù)類型指定具體類型,并告訴系統(tǒng)這是一個(gè)泛型方法 MethodInfo genericMethodNew = genericMethod.MakeGenericMethod(typeof(int), typeof(int));

//對泛型方法進(jìn)行調(diào)用,傳入的第一個(gè)參數(shù)是調(diào)用哪個(gè)實(shí)例的這個(gè)泛型方法,第二個(gè)參數(shù)是傳入?yún)?shù)
genericMethodNew.Invoke(objectGeneric, new object[] { 1, 4 });

總結(jié)

以上是生活随笔為你收集整理的.NET 反射原理及其运用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。