反射的用法和好處
今天我們就來說一說反射(Reflection ),
反射是什麽呢?反射是動態獲取程序集的元數據(metadata)的一種技術。反射是.NetFramework類庫提供的幫助類,動態加載dll實現程序的可配置可擴展。
首先我們來看一個簡單的實現反射的例子,我們先創建整個框架
IDAL裏面是一個接口,接口裏面有一個Query方法,
using System; namespace Reflect.IDAL { public interface IHelper { void Query(); } }
假設這個Query方法就是鏈接數據庫的某個方法,下面我們就實現它
現在有一個sqlserver數據庫,我們要寫DAL數據Helper類來實現
using Reflect.IDAL; using System; namespace Reflect.DAL { public class SqlServerHelper : IHelper { public SqlServerHelper() { Console.WriteLine("這是SqlHelper的構造函數"); } public void Query() { //throw new NotImplementedException(); Console.WriteLine("這是一個假的實現sqlhelp的方法"); } } }
假設我們現在鏈接了數據庫,然後我們就需要在控制臺輸出一下,在控制臺實現之前,我們就要配置一下,反射就是為了實現可配置的嘛。
打開app.Config 添加appSetting節點如下
<appSettings> <!--<add key="DAL" value="Reflect.DAL,Reflect.DAL.SqlServerHelper"/>--> <add key="DAL" value="Reflect.MySql.DAL,Reflect.MySql.DAL.MySqlHelper"/> </appSettings>
這裏有兩個key,第一個是sqlServer鏈接的配置,第二個是MySql的鏈接配置,sqlServer的配置被註釋了,我們實現的也就是mysql的配置,mysql的DAL的代碼和sqlServer的類似。
using Reflect.IDAL; using System; namespace Reflect.MySql.DAL { public class MySqlHelper : IHelper { public MySqlHelper() { Console.WriteLine("這是MySqlHelper的構造函數"); } public void Query() { Console.WriteLine("這是一個假的實現MySqlHelper的方法"); } } }
這個也就是反射的已擴展,當所有的類定義好以後需要擴展不需要修改實現的代碼,下面就是控制臺的代碼
using Reflect.DAL; using Reflect.IDAL; using System; using System.Configuration; using System.Reflection; namespace Reflection { class Program { static void Main(string[] args) { Console.WriteLine("****************從這裏開始反射*************"); //SqlServerHelper sqlhelper = new SqlServerHelper(); //sqlhelper.Query(); string HelperConfig = ConfigurationManager.AppSettings["DAL"].ToString(); Assembly assenbly = Assembly.Load(HelperConfig.Split(‘,‘)[0]);//動態的加載dll Type typeHelper = assenbly.GetType(HelperConfig.Split(‘,‘)[1]);//找出具體的類型 object oHelper = Activator.CreateInstance(typeHelper);//創建對象等同於new IHelper ihelper = (IHelper)oHelper;//將object類型轉換為接口類型 ihelper.Query(); Console.ReadKey(); } } }
//SqlServerHelper sqlhelper = new SqlServerHelper(); //sqlhelper.Query();
這裏被註釋的兩行代碼其實也能實現,而且是我們平常實現的常用做法,可是他的局限性就是在擴展方面需要修改代碼,而我們在編寫程序的時候所要求的是對擴展開放,對修改密封,這裏他就不太好用了。
當上面所有的實現之後,我們運行程序
我們要是想要更換數據庫,只要修改配置文件,不需要修改代碼就能實現,是不是好了很多。
<appSettings> <add key="DAL" value="Reflect.DAL,Reflect.DAL.SqlServerHelper"/> <!--<add key="DAL" value="Reflect.MySql.DAL,Reflect.MySql.DAL.MySqlHelper"/>--> </appSettings>
使用反射的優缺點優點:
優點:反射提高了程序的靈活性和擴展性,降低耦合性,提高自適應能力。它允許程序創建和控制任何類的對象,無需提前硬編碼目標類;
缺點:(1)性能問題:使用反射基本上是一種解釋操作,用於字段和方法接入時要遠慢於直接代碼。因此反射機制主要應用在對靈活性和擴展性要求很高的系統框架上,普通程序不建議使用。
(2)使用反射會模糊程序內內部邏輯:程序員希望在源代碼中看到程序的邏輯,反射等繞過了源代碼的技術,因而會帶來維護問題。反射代碼比相應的直接代碼更復雜。
我們需要在使用反射的時候一定要明確反射的有缺點,這樣才能讓程序更加完善。
反射的用法和好處