一:認識程序集
只要是使用VS就會和程序集打交道,我們通過編輯和生產可執行程序就會自動生成程序集。那麼什麼事程序集呢,.net中的dll與exe文件的都是程序集(Assembly)。
可以看做是一堆相關類打包的包,相當於java中的jar包(*);
程序集包含:類型元數據,程序集元數據,IL代碼,資源文件
類型元數據:描述在代碼中定義的每一類型和成員的二進制形式。
程序集元數據:程序集清單,版本號,名稱等;
IL代碼:被微軟封裝到了exe和IL中。
資源文件:每個程序集都有自己的名稱,版本等信息,都可以通過AssemblyInfo.cs文件來自己定義。
好處:程序中只引用必須的程序集,減小程序的尺寸。可以封裝一個代碼,只提供必要的訪問接口。
二:反射學習
反射看似很高深,聽起來不太的容易理解,但是我們要是經常的使用它,那就會變得很簡單。
vs的智能提示就是通過反射來獲取到類的屬性,方法等,還有反編譯工具也是。
定義:反射就是動態的獲取程序集中的元數據來操作類型的。反射就是直接通過調用.dll來創建對象,調用成員的。通過類型元數據來獲取對象的一些相關信息,並且還可以實例化對象調用方法等,這個就是反射。
Type類是實現反射的重要類,通過它可以獲取到類中的所有信息包括方法,屬性等,可以動態的調用類,方法,Type是對類的描述,反射讓創建對象的方式發生了變化。
eg1:
讀取Clb.dll文件,讀取裡面所有的類(Type)。
Clb.dll文件
namespace Clb { public class Class1 { //屬性 private int Age { get; set; } //方法 public void SayHi() { Console.WriteLine("你好世界 ?"); } //接口 public interface IFlyable { void Fly(); } //委托 public delegate void MyDelegate(); } }
main()方法
static void Main(string[] args) { //通過Assembly來取到本地的程序集。 Assembly asm = Assembly.LoadFile("C:/Clb.dll"); //注意它的返回值 Type[] type=asm.GetTypes(); //得到所有的類型,注意返回值。 foreach (Type item in type) { Console.WriteLine(item.Name); } Console.Read(); }
獲取只有public類型的
//只獲取public類型 Type[] type = asm.GetExportedTypes();
出現錯誤如下,解決辦法是我們的設置有問題,在調試--選項和設置---常規(下圖),這樣就可以讀取到本地的dll文件了。
eg:加載Class1中的所有方法。
//加載程序集 Assembly asm = Assembly.LoadFile("C:/Clb.dll"); //獲取Class1下這個類型,typeclass描述Class1類的type,裡面存儲的是class1的一些相關信息,。 Type typeclass= asm.GetType("Clb.Class1"); //獲取class1中的所有方法 ,注意返回值。 MethodInfo[] minfo= typeclass.GetMethods(); foreach (MethodInfo item in minfo) { Console.WriteLine(item.Name); } Console.Read();
下面圖片裡面的方法我們的類中沒有,那是我們object基類的一些公共方法。
eg:
通過反射來創建對象,調用類庫中的方法。
//1:加載程序集 Assembly asm = Assembly.LoadFile("C:/Clb.dll"); //2:獲取Class1下這個類型,typeclass描述Class1類的type,裡面存儲的是class1的一些相關信息,。 Type typeclass= asm.GetType("Clb.Class1"); //3:獲取class1中的所有方法 ,注意返回值。 MethodInfo minfo = typeclass.GetMethod("SayHi"); Console.WriteLine(minfo.Name); //創建一個Class1類型對象 object obj = Activator.CreateInstance(typeclass); //通過反射來調用方法 minfo.Invoke(obj, null); Console.Read();
三:Type類的使用
通過類獲取Type;通過對象獲取類的Type,通過Assembly類獲取Type。
Person p=new Person(); //通過基類的GetType類獲取Type Type t= p.GetType(); //通過typeof來獲取。 Type ts = typeof (Person); //通過程序集來獲取; Assembly asm = Assembly.LoadFile("C:/Clb.dll"); Type tss = asm.GetType("Clb.dll.Person");