C#类型反射、晚期绑定、特性编程的使用背景与分析
???? 任何編程語言的任何特點都是有存在的道理的,C#中有些特點也許我們不求甚解的用過,但是如果知道它的使用背景與原理,使用起來將更加得心應手。本文主要分析的就是C#中的類型反射、晚期綁定、特性編程。闡釋為什么要用這些語言特點?
???? 首先看一下簡單項目的需求:程序員開發了很多模塊,每個模塊對應相應的功能,不同的用戶可能需要使用的模塊不一樣,模塊以插件的形式與系統集成,也就是提供給用戶一個自定義模塊的功能。
???? 更加形象的比如:一個通用的圖書館里系統中有普通老師模塊、有院長模塊、有校長模塊、有學生模塊,這些模塊都具有借書的功能(每個模塊借書本數不一樣);這個通用的系統可能給很多學校使用,每個學校根據自己的需求選擇模塊。
對于上面這個需求分析,1、由于這些模塊都具有借書的功能,首先想到的是建立一個接口,接口中包含一個借書的函數,所有模塊都要實現這個接口。
2、分別實現這些插件模塊,編譯成程序集DLL文件。
3、由于這是一個通用的系統,模塊的選擇應該由用戶決定,因此我們不能預先把所有的模塊功能都編譯到系統中去(晚期綁定派上用場)。
4、用戶選擇一個模塊(DLL文件),就相當于要加載一個程序集DLL(動態加載的概念),此時的DLL與用C/C++編寫的DLL不一樣,它是由微軟中間語言IL組成的,里面記錄了
??? DLL所有信息的元數據。
5、需要調用具體某個DLL模塊中的具體借書函數,這個時候就需要從動態加載的DLL中獲取到相應的類,實例化類,調用類的成員函數,這個就需要反射來干了。
6、有的時候在大型項目中,每個模塊可能有不同的子部門來做,因此每個模塊應該包好有這些部門的基本信息,這個時候在編寫模塊的功能時候,就可利用C#中的特性編程了,利用特性可以
???? 給模塊附加上額外的信息,這些信息會被編譯到程序集中,同理我們也可以反射出這些信息來。
下面是一個簡單代碼的例子:利用了這些特性
插件接口的定義:
View Code using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace CommonTypes {//定義一個接口public interface IAppDll{void DoThing(); }//自定義特性類 [AttributeUsage(AttributeTargets.Class)]public sealed class CarInfoAttribute : System.Attribute {public string name{ get; set;} }}根據上面的定義的接口約束,開發第三方的插件
View Code using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;using System.Windows.Forms; using CommonTypes;namespace CsharpDll {[CarInfo(name="這是第三方生產的插件")]public class CsharpModule:IAppDll{public void DoThing()//實現接口中的函數 {MessageBox.Show("正在調用的是Csharp插件模塊");} } }在窗體程序中調用第三方插件
View Code using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;using System.Reflection; using CommonTypes;namespace WindowsFormsApplication1 {public partial class Form1 : Form{public Form1(){InitializeComponent();}private void openToolStripMenuItem_Click(object sender, EventArgs e){//選擇一個插件加載OpenFileDialog OFD = new OpenFileDialog();if (OFD.ShowDialog() == DialogResult.OK) {if (!LoadModule(OFD.FileName))MessageBox.Show("沒有成功加載第三方的插件!");}}private bool LoadModule(string path) {bool FindModule = false;Assembly asm = null;try{//加載指定路徑下的程序集asm = Assembly.LoadFrom(path);}catch (Exception ex) {MessageBox.Show(ex.Message);return FindModule;}//得到程序集中所有的IAppDll接口兼容的累var ClassTypes = from t in asm.GetTypes()where t.IsClass &&(t.GetInterface("IAppDll") != null)select t;//創建對象,并調用類中的方法foreach (Type t in ClassTypes) {FindModule = true;//使用晚期綁定建立類型,強制轉換為接口類型IAppDll someApp =(IAppDll)asm.CreateInstance(t.FullName, true);someApp.DoThing();listBox1.Items.Add(t.FullName);//顯示插件的相關信息 DisplayCarinfo(t);}return FindModule;}//顯示插件的信息private void DisplayCarinfo(Type t) {var info = from carAtr in t.GetCustomAttributes(false)where (carAtr.GetType() == typeof(CarInfoAttribute))select carAtr;//顯示特性的屬性foreach (CarInfoAttribute cia in info) {MessageBox.Show(cia.name); }}} }?
轉載于:https://www.cnblogs.com/guoyuanwei/archive/2012/06/12/2545397.html
總結
以上是生活随笔為你收集整理的C#类型反射、晚期绑定、特性编程的使用背景与分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Windows Phone Dev No
- 下一篇: IOS基础:声音调用