1. 概述反射
- 通過反射可以提供型別資訊,從而使得我們開發人員在運行時能夠利用這些資訊構造和使用物件,
- 反射機制允許程式在執行程序中動態地添加各種功能,
2. Type類的介紹
- 是BCL(基底類別庫)宣告的一個抽象類,所有它不能被實體化
- 對于程式中用到的每一個型別,CLR(公共語言運行時)都會創建一個包含這個型別資訊的Type型別的物件
- 程式中用到的每一個型別都會關聯到獨立的Type型別的物件
- 不管創建的型別有多少個實體,只有一個Type物件會關聯到所有這些實體
2.1 Type類的部分常見成員
成員 成員型別 描述 Name 屬性 回傳型別的名字 FullName 屬性 回傳資料型別的完全限定名(包括命名空間名) NameSpace 屬性 回傳包含資料型別宣告的命名空間 Assembly 屬性 回傳宣告型別的程式集,如果型別是泛型的,回傳定義這個型別的程式集 GetConstructor(), GetConstructors() 方法 回傳ConstructorInfo型別,用于取得該類的建構式的資訊 GetEvent(), GetEvents() 方法 回傳EventInfo型別,用于取得該類的事件的資訊 GetField(), GetFields() 方法 回傳FieldInfo型別,用于取得該類的欄位(成員變數)的資訊 GetInterface(), GetInterfaces() 方法 回傳InterfaceInfo型別,用于取得該類實作的介面的資訊 GetMember(), GetMembers() 方法 回傳MemberInfo型別,用于取得該類的所有成員的資訊 GetMethod(), GetMethods() 方法 回傳MethodInfo型別,用于取得該類的方法的資訊 GetProperty(), GetProperties() 方法 回傳PropertyInfo型別,用于取得該類的屬性的資訊
3. 如何獲取Type型別
3.1GetType()和typeof() 方法 兩者都是回傳Syetem.Type的參考,(private和protected修飾的成員也可以訪問到)
3.1.1 GetType()
1.GetType()是從Syetem.object中基礎的方法,
2.GetType()必須要通過型別的實體點出這個方法,
3.1.2 typeof()
1.typeof(xx)是公開的運算子,
2.typeof(xx)中xx只能是int,string 等型別及自定義型別,不能是實體,
3.2 不同點
1.GetType()回傳的是Type(型別)
2.typeof(xx) 回傳的是xx Class(類)的型別
1 //實體一個用戶類 2 User user = new User(); 3 //GetType()方法 4 Type getType = user.GetType(); 5 //typeof(xx) 方法 6 Type typeOf = typeof(User); 7 //判斷是否相等 8 if (getType == typeOf) 9 { 10 //這里相等 11 Console.WriteLine("我在這"); 12 }
4.Type類方法
1: 一旦有了Type物件就可以使用GetMethodInfo()方法獲取此型別支持的方法串列,該方法回傳一個MethodInfo 物件陣列,MethodInfo物件描述了主調型別所支持的方法,他位于System.Reflection命名空間中
2: MethodInfo類派生于MethodBase抽象類,而MethodBase類繼承了MemberInfo類,因此我們能夠使用這三個類定義的屬性和方法,例如,使用Name屬性得到方法名稱,這里有兩個重要的成員:
3: ReturnType屬性 :為Type型別的物件,能夠提供方法的回傳型別資訊 GetParameters()方法 :回傳引數串列,引數資訊以陣列形式保存在PatameterInfo物件中,PatameterInfo類定義了大量描述引數資訊的屬性和方法,這里也列出兩個常用的屬性 :Name(包含引數名稱資訊的字串),ParameterType(引數型別的資訊),
//創建實體 Sublevel sublevel = new Sublevel(); //獲取型別 Type sublevelType = sublevel.GetType(); //獲取型別的方法串列 //BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public 這個有一個注意點 //實際上至少要有Instance(或Static)與Public(或NonPublic)標記,否則將不會獲取任何方法, MethodInfo[] obj = sublevelType.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public); //遍歷所有的方法 foreach (MethodInfo item in obj) { //回傳方法的回傳型別 Console.Write(item.ReturnType.Name); //回傳方法的名稱 Console.Write(" "+item.Name+"("); //獲取方法的回傳引數串列 ParameterInfo[] parameterss = item.GetParameters(); foreach (var parameters in parameterss) { //引數型別名稱 Console.Write(parameters.ParameterType.Name); //引數名稱 Console.Write(" "+parameters.Name+","); } Console.WriteLine(")"); }

執行的結果,獲取了所有的方法,包括了方法的方法名稱,方法的回傳型別,方法引數串列,
5.方法的使用
前面我們講了放的顯示,但是只能看到不能用就不好了呀!!!
5.1:GetMethods()方法的另一種形式
這種形式可以制定各種標記,已篩選想要獲取的方法,他的通用形式為:MethodInfo[] GetMethods(BindingFlags bindingAttr)BindingFlags是一個列舉,列舉值有(很多只列出4個吧)
- Instance:獲取實體方法
- NonPublic: 獲取非公有方法
- Public: 獲取共有方法
- Static:獲取靜態方法
GetMethods(BindingFlags bindingAttr)這個方法,引數可以使用or把兩個或更多標記連接在一起,實際上至少要有Instance(或Static)與Public(或NonPublic)標記,否則將不會獲取任何方法,del.GetType();
public static void Method<T>(T model) { //獲取泛性的Type型別 Type objType = model.GetType(); //獲取泛性的方法串列 MethodInfo[] mthodInfos = objType.GetMethods(); //回圈方法 foreach (var item in mthodInfos) { //獲取方法的所有引數串列 var parameters = item.GetParameters(); //過濾沒用方法 //1:查看是不是有引數的方法 //2:查看這個方法的回傳型別是不是我們想要的 //3:查看這個方法的回傳型別是不是我們想要的 if (parameters.Any() && parameters[0].ParameterType == typeof(int) && item.ReturnType != typeof(void)) { //呼叫方法 object[] parametersObj = new object[] { 5 }; //呼叫實體方法 //第一個引數是我們的物體,后面是我們的引數(引數是一個陣列,多個引數按照順序來傳遞,沒有引數可以為null) //如果我們的方法是一個靜態方法 ,這個引數可以為null (不是靜態的就會報錯) Console.WriteLine(item.Invoke(model, parametersObj)); } } }

6.DataTable轉Model(List)
在剛剛學.net 的時候,我們從資料庫查詢出一個DataTable的時候想要轉成Model或者LIst的時候我們需要手動的寫遍歷,超級麻煩(在沒有接觸MVC的時候我就是)
/// <summary> /// DataTable轉換 /// </summary> public class TransitionDataTable { /// <summary> /// DataTable轉換模型 /// </summary> /// <typeparam name="T">模型型別</typeparam> /// <param name="obj">模型</param> /// <param name="data">資料行</param> /// <returns></returns> public T DataSetBindModel<T>(T obj, DataTable data) where T : class, new() { T result = new T(); foreach (DataRow item in data.Rows) { result = assignmentClass(obj, item); } return result; } /// <summary> /// DataTable轉換List /// </summary> /// <typeparam name="T">模型型別</typeparam> /// <param name="obj">模型</param> /// <param name="data">資料行</param> /// <returns></returns> public List<T> DataSetBindList<T>(T obj, DataTable data) where T : class, new() { List<T> result = new List<T>(); foreach (DataRow item in data.Rows) { result.Add(assignmentClass(obj, item)); } return result; } /// <summary> /// DataRow 轉換成模型 /// </summary> /// <typeparam name="T">模型型別</typeparam> /// <param name="obj">模型</param> /// <param name="row">資料行</param> /// <returns></returns> private T assignmentClass<T>(T obj, DataRow row) where T : class, new() { if (obj == null) { obj = new T(); } Type type = obj.GetType(); //得到型別的所有屬性,也就是表對應的物體模型的所有屬性 //嗮選一下只要公開的 PropertyInfo[] properts = type.GetProperties(BindingFlags.Instance | BindingFlags.Public); if (properts.Any()) { foreach (PropertyInfo item in properts) { if (row.Table.Columns.IndexOf(item.Name) != -1) { if (row[item.Name] != null && row[item.Name] != DBNull.Value) { item.SetValue(obj, row[item.Name]); } } } } return obj; } }View Code
呼叫
static void Show() { DataTable data = new BDHelper().GetData("select * from Jack_News_TNews"); News news = new News(); var list = new TransitionDataTable().DataSetBindList(news, data); }
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/91619.html
標籤:.NET Core
