1. 程式人生 > >反射的用法和好處

反射的用法和好處

void 配置 更換 exception 帶來 div framework 行程 int

今天我們就來說一說反射(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)使用反射會模糊程序內內部邏輯:程序員希望在源代碼中看到程序的邏輯,反射等繞過了源代碼的技術,因而會帶來維護問題。反射代碼比相應的直接代碼更復雜。

我們需要在使用反射的時候一定要明確反射的有缺點,這樣才能讓程序更加完善。


反射的用法和好處