標籤:
//Assembly:
1..net的概念 .exe .dll (供載入用 本身不能執行 無入口函數主函數)
2.包含
類型中繼資料 (代碼中定義的類型)
組件中繼資料 (描述程式集自身)
IL代碼
資源檔
->使用程式集的好處:一是減小程式本身大小(因為可以只調用需要用到的dll)分模組 二是封裝代碼 向外提供介面
->如何添加程式集的引用:添加路徑、項目引用、GAC(全域組件快取) //不能迴圈添加引用 //C#中可調用其他程式所寫的dll檔案
//---------------------------------reflection--------------------------------------------------------------------
反射:可以理解為一種技術手段 拿到類型中繼資料
直接通過.dll來建立對象,調用成員
我們先在同一個項目裡建立主程式,然後建立另外一個程式集(在同一個項目下)
這裡TestClassLibrary 是一個類庫 在Class1.cs中添加一些類型 類啊 介面啊 委託啊 什麼的:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace TestClassLibary 8 { 9 public class Class110 {11 12 }13 14 internal class PrivateMyClass15 {16 17 }18 19 public class Person20 {21 public string Name { get; set; }22 public int Age { get; set; }23 public string Email { get; set; }24 25 }26 27 public delegate void MyDelegate();28 29 public interface IFlyable30 {31 void Fly();32 }33 34 }
類庫
然後右鍵產生,找到Debug目錄下的dll檔案路徑:
F:\Cheng_20140819\VS2012_WorkSpace\_Assembly\Assembly\TestClassLibary\bin\Debug\TestClassLibrary.dll
這樣在我們主程式中就可以動態載入啦.. ^_~
醬紫:
1 #region 擷取另外一個程式集中的類型 2 //動態載入程式集 3 Assembly ass = Assembly.LoadFile(@"F:\Cheng_20140819\VS2012_WorkSpace\Assembly\Assembly\TestClassLibary\bin\Debug\TestClassLibary.dll"); 4 5 //這裡的GetType() 等價於 TypeOf(Assembly) 不能擷取所有程式集中所有類型 6 7 //利用GetTypes擷取所有類型 public internal 都能拿到 8 Type[] ts = ass.GetTypes(); 9 foreach (Type item in ts)10 {11 Console.WriteLine( item.Name);12 }13 14 //只擷取公開的類型15 //擷取匯出的類型16 Type[] publicTypes = ass.GetExportedTypes();17 foreach (Type item in publicTypes)18 {19 Console.WriteLine("--->>"+item.Name);20 }21 #endregion
當然我們若是要擷取指定的類型 調用重載:
Assembly ass = Assembly.LoadFile(@"F:\Cheng_20140819\VS2012_WorkSpace\20151129_Heima_Day11_Assembly\Assembly\TestClassLibary\bin\Debug\TestClassLibary.dll");
//---------------------------------------------這裡假設在擷取到的Person類中 有Add方法 一個傳回值 兩個參數 添加方法之後要記得重建
//擷取特定的Type
Type personType = ass.GetType("TestClassLibary.Person"); //類型需要完全限定名稱 : 記得帶上命名空間喲~
//根據特定的Type 來建立對象
object personObj = Activator.CreateInstance(personType);
//擷取特定的方法
MethodInfo method = personType.GetMethod("Add");
//調用
object obj= method.Invoke(personObj, new object[] { 2, 3 }); //參數1 代表擷取的類型的對象 ,參數2 代表調用的方法的參數列表
//--------------------------------調用屬性---------------------
1 Assembly ass = Assembly.LoadFile(@"F:\Cheng_20140819\VS2012_WorkSpace\Assembly\Assembly\TestClassLibary\bin\Debug\TestClassLibary.dll"); 2 3 Type t = ass.GetType("TestClassLibary.Person"); 4 5 object obj = Activator.CreateInstance(t); 6 7 PropertyInfo pifo = t.GetProperty("Name"); 8 9 pifo.SetValue(obj, "cheng");10 11 MethodInfo mifo = t.GetMethod("WriteName");12 13 mifo.Invoke(obj, null);
//--------------------------------利用特定的建構函式
1 #region 手動尋找建構函式 並且調用該建構函式來建立類型的對象 2 Assembly ass = Assembly.LoadFile(@"F:\Cheng_20140819\VS2012_WorkSpace\20151129_Heima_Day11_Assembly\Assembly\TestClassLibary\bin\Debug\TestClassLibary.dll"); 3 4 Type personType=ass.GetType("TestClassLibary.Person"); 5 6 //這裡使用 ctor GetConstructor() 其參數列表就 是指定的建構函式的列表 7 ConstructorInfo ctor= personType.GetConstructor(new Type[] { typeof(string),typeof(int),typeof(string)}); 8 object o = ctor.Invoke(new object[] {"ccc",20,"[email protected]" }); 9 Console.WriteLine(o.ToString());10 MethodInfo mInfo = personType.GetMethod("WriteName");11 mInfo.Invoke(o, null);12 13 #endregion
C#_Assembly-Reflection_程式集與反射