常見反射類html
類型 | 做用 |
---|---|
Assembly | 經過此類能夠加載操縱一個程序集,並獲取程序集內部信息 |
EventInfo | 該類保存給定的事件信息 |
FieldInfo | 該類保存給定的字段信息 |
MethodInfo | 該類保存給定的方法信息 |
MemberInfo | 該類是一個基類,它定義了EventInfo、FieldInfo、MethodInfo、PropertyInfo的多個公用行爲 |
Module | 該類可使你能訪問多個程序集中的給定模塊 |
ParameterInfo | 該類保存給定的參數信息 |
PropertyInfo | 該類保存給定的屬性信息 |
經過Assembly能夠動態加載程序集,並查看程序集的內部信息,其中最經常使用的就是Load()這個方法。性能
Assembly assembly=Assembly.Load("MyAssembly");
利用Assembly的object CreateInstance(string) 方法能夠反射建立一個對象,參數爲類名。spa
Type是最經常使用到的類,經過Type能夠獲得一個類的內部信息,也能夠經過它反射建立一個對象。通常有三個經常使用的方法可獲得Type對象。code
Type type=typeof(Example);
Example example=new Example(); Type type=example.GetType();
Type type=Type.GetType("MyAssembly.Example",false,true);
注意第一個參數是類名,第二個參數表示若找不到對應類時是否拋出異常,第三個參數表示類名是否區分大小寫。htm
例子:
咱們最多見的是利用反射與Activator結合來建立對象。對象
Assembly assembly= Assembly.Load("MyAssembly"); Type type=assembly.GetType("Example"); object obj=Activator.CreateInstance(type);
Type type=typeof(Example); MethodInfo[] listMethodInfo=type.GetMethods(); foreach(MethodInfo methodInfo in listMethodInfo) Cosole.WriteLine("Method name is "+methodInfo.Name);
Assembly assembly= Assembly.Load("MyAssembly"); Type type=assembly.GetType("Example"); object obj=Activator.CreateInstance(type); MethodInfo methodInfo=type.GetMethod("Hello World"); //根據方法名獲取MethodInfo對象。 methodInfo.Invoke(obj,null); //第二個參數類型爲object[],表明Hello World方法的對應參數,輸入值爲null表明沒有參數。
Type type=typeof(Example); PropertyInfo[] listPropertyInfo=type.GetProperties(); foreach(PropertyInfo propertyInfo in listPropertyInfo) Cosole.WriteLine("Property name is "+ propertyInfo.Name);
Assembly assembly=Assembly.Load("MyAssembly"); Type type=assembly.GetType("Example"); object obj=Activator.CreateInstance(type); PropertyInfo propertyInfo=obj.GetProperty("Name"); //獲取Name屬性對象 var name=propertyInfo.GetValue(obj,null); //獲取Name屬性的值 PropertyInfo propertyInfo2=obj.GetProperty("Age"); //獲取Age屬性對象 propertyInfo.SetValue(obj,34,null); //把Age屬性設置爲34
經過 System.Reflection.FieldInfo 能查找到類裏面的字段
它包括有兩個經常使用方法SetValue(object ,object )和GetValue(object) 由於使用方法與反射屬性很是類似,在此再也不多做介紹。
(略)blog
經過System.Reflection.MemberInfo的GetCustomAttributes(Type,bool)就可反射出一個類裏面的特性,如下例子能夠反射出一個類的全部特性。
代碼:接口
Type type=typeof("Example"); object[] typeAttributes=type.GetCustomAttributes(false); //獲取Example類的特性 foreach(object attribute in typeAttributes) Console.WriteLine("Attributes description is "+attribute.ToString());
經過下面例子,能夠獲取Example類Name屬性的全部特性。
代碼:事件
public class Example { [DataMemberAttribute] publics string Name {get;set;} } Type type = typeof(Example); PropertyInfo propertyInfo=type.GetProperty("Name"); //獲取Example類的Name屬性 foreach (object attribute in propertyInfo.GetCustomAttributes(false)) //遍歷Name屬性的全部特性 Console.WriteLine(「Property attribute: "+attribute.ToString());
雖然反射有不少奧妙之處,但要注意使用反射生成對象會耗費不少性能,所能必須瞭解反射的特性,在合適的地方使用。最多見例子就是利用單體模式與反射一併使用, 在BLL調用DAL的時候,經過一個反射工廠生成DAL實例。ip
namespace Project.Common { public class Factory { //記錄dal的對象 private static Hashtable dals; //用assemblyString記錄DAL程序集的全名稱 private static string assemblyString = ConfigurationManager.AppSettings["LinqDAL"]; private static Assembly assembly; static Factory() { dals = new Hashtable(); assembly = Assembly.Load(assemblyString); } private static object CreateInstance(string typeName) { //當第一次加載時,將反射對象保存於dals集合裏 if (!dals.ContainsKey(typeName)) { //建立反射對象 object object1 = assembly.CreateInstance(typeName); if (object1 == null) throw new Exception("未能建立此對象"); //把對象加入dals集合 dals["typeName"] = object1; } return dals["typeName"]; } public static IExampleDAL CreateExampleDAL() { return (IExampleDAL)CreateInstance(assemblyString + ".ExampleDAL"); } } class Program { //利用工廠模式生成對象 static void Main(string[] args) { IExampleDAL iExampleDAL=Factory.CreateExampleDAL(); Console.ReadKey(); } } } namespace Project.IDAL { public interface IExampleDAL { ///<summary> /// 插入Example行,若插入成功,則返回新增Example的行數 ///</summary> ///<param name="example">Example對象</param> ///<returns>返回新增Example行數,默認值爲-1</returns> int AddExample(Example example); ///<summary> /// 更新Example表,Update成功返回已經更新的數據條數,失敗返回-1 ///</summary> ///<param name="example">Example對象</param> ///<returns>Update成功返回已經更新的數據條數,失敗返回-1</returns> int UpdateExample(Example example); ///<summary> /// 刪除Example表中ID等於exampleID的行,返回已刪除行數 ///</summary> ///<param name="exampleID">Example對象的ID值</param> ///<returns>返回刪除行數</returns> int DeleteExample(int exampleID); ///<summary> /// 獲取Example表的全部行 ///</summary> ///<returns>返回Example表中的全部Example對象</returns> IList<Example> GetList(); ///<summary> /// 根據ID獲取對應Example對象 ///</summary> ///<param name="id"></param> ///<returns></returns> Example GetExampleByID(int id); } } namespace Project.DAL { public class ExampleDAL:IExampleDAL { public int AddExample(Example example) { //實現AddExample方法 } } }
本篇文章轉載於 風塵浪子的《反射的奧妙》