C#反射 獲取程式集資訊和通過類名建立類例項
阿新 • • 發佈:2018-12-26
C#反射獲取程式集資訊和通過類名建立類例項 。
System.Reflection 名稱空間:包含通過檢查託管程式碼中程式集、模組、成員、引數和其他實體的元資料來檢索其相關資訊的型別。
Assembly 類:表示一個程式集,它是一個可重用、無版本衝突並且可自我描述的公共語言執行庫應用程式構造塊。
1、反射獲取程式集資訊
1.1 建立AssemblyResult.cs類,用於儲存結果
/// <summary> /// 反射結果類 /// </summary> public class AssemblyResult { /// <summary> /// 程式集名稱 /// </summary> public List<string> AssemblyName { get; set; } /// <summary> /// 類名 /// </summary> public List<string> ClassName { get; set; } /// <summary> /// 類的屬性 /// </summary> public List<string> Properties { get; set; } /// <summary> /// 類的方法 /// </summary> public List<string> Methods { get; set; } }
1.2 建立AssemblyHandler.cs反射處理類
注意:要引用System.Reflection 名稱空間。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Reflection; using System.IO; namespace MyStudyFrom { /// <summary> /// 反射處理類 /// </summary> public class AssemblyHandler { string path = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + @"/MyDLL/"; /// <summary> /// 獲取程式集名稱列表 /// </summary> public AssemblyResult GetAssemblyName() { AssemblyResult result = new AssemblyResult(); string[] dicFileName = Directory.GetFileSystemEntries(path); if(dicFileName!=null) { List<string> assemblyList = new List<string>(); foreach(string name in dicFileName) { assemblyList.Add(name.Substring(name.LastIndexOf('/') + 1)); } result.AssemblyName = assemblyList; } return result; } /// <summary> /// 獲取程式集中的類名稱 /// </summary> /// <param name="assemblyName">程式集</param> public AssemblyResult GetClassName(string assemblyName) { AssemblyResult result = new AssemblyResult(); if (!String.IsNullOrEmpty(assemblyName)) { assemblyName = path + assemblyName; Assembly assembly = Assembly.LoadFrom(assemblyName); Type[] ts = assembly.GetTypes(); List<string> classList = new List<string>(); foreach (Type t in ts) { //classList.Add(t.Name); classList.Add(t.FullName); } result.ClassName = classList; } return result; } /// <summary> /// 獲取類的屬性、方法 /// </summary> /// <param name="assemblyName">程式集</param> /// <param name="className">類名</param> public AssemblyResult GetClassInfo(string assemblyName, string className) { AssemblyResult result = new AssemblyResult(); if (!String.IsNullOrEmpty(assemblyName) && !String.IsNullOrEmpty(className)) { assemblyName = path + assemblyName; Assembly assembly = Assembly.LoadFrom(assemblyName); Type type = assembly.GetType(className,true,true); if (type != null) { //類的屬性 List<string> propertieList = new List<string>(); PropertyInfo[] propertyinfo = type.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); foreach (PropertyInfo p in propertyinfo) { propertieList.Add(p.ToString()); } result.Properties = propertieList; //類的方法 List<string> methods = new List<string>(); MethodInfo[] methodInfos = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo mi in methodInfos) { methods.Add(mi.Name); //方法的引數 //foreach (ParameterInfo p in mi.GetParameters()) //{ //} //方法的返回值 //string returnParameter = mi.ReturnParameter.ToString(); } result.Methods = methods; } } return result; } } }
2、通過類名建立類例項
2.1、假設你要反射一個 DLL 中的類,並且沒有引用它(即未知的型別):
Assembly assembly = Assembly.LoadFile("程式集路徑,不能是相對路徑"); // 載入程式集(EXE 或 DLL)
object obj = assembly.CreateInstance("類的完全限定名(即包括名稱空間)"); // 建立類的例項
2.2、若要反射當前專案中的類可以為:
Assembly assembly = Assembly.GetExecutingAssembly(); // 獲取當前程式集
object obj = assembly.CreateInstance("類的完全限定名(即包括名稱空間)"); // 建立類的例項,返回為 object 型別,需要強制型別轉換
2.3、也可以為:
object obj = type.Assembly.CreateInstance(type);
=======================================================
補充:
1)反射建立某個類的例項時,必須保證使用類的完全限定名(名稱空間 + 類名)。Type.GetType 方法返回 null 則意味搜尋元資料中的相關資訊失敗(反射失敗),請確保反射時使用類的完全限定名。
2)反射功能十分強大,沒有什麼不能實現的。若實現“跨程式集”,請使用第一種方法建立類的例項,並反射該例項的欄位、屬性、方法、事件... 然後動態呼叫之。