//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 Class1 10 { 11 12 } 13 14 internal class PrivateMyClass 15 { 16 17 } 18 19 public class Person 20 { 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 IFlyable 30 { 31 void Fly(); 32 } 33 34 }
然后右键生成,找到Debug目录下的dll文件路径:
F:Cheng_20140819VS2012_WorkSpace\_AssemblyAssemblyTestClassLibaryinDebugTestClassLibrary.dll
这样在我们主程序中就可以动态加载啦.. ^_~
酱紫:
1 #region 获取另外一个程序集中的类型 2 //动态加载程序集 3 Assembly ass = Assembly.LoadFile(@"F:Cheng_20140819VS2012_WorkSpaceAssemblyAssemblyTestClassLibaryinDebugTestClassLibary.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_20140819VS2012_WorkSpace20151129_Heima_Day11_AssemblyAssemblyTestClassLibaryinDebugTestClassLibary.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_20140819VS2012_WorkSpaceAssemblyAssemblyTestClassLibaryinDebugTestClassLibary.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_20140819VS2012_WorkSpace20151129_Heima_Day11_AssemblyAssemblyTestClassLibaryinDebugTestClassLibary.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,"CCC@sina.cn" }); 9 Console.WriteLine(o.ToString()); 10 MethodInfo mInfo = personType.GetMethod("WriteName"); 11 mInfo.Invoke(o, null); 12 13 #endregion
12月02日 补充:
拿到某个类型PType之后 要拿到私有方法的话 需要调用 :MethodInfo privateMethodName= PType.GetMethod("SayHi",BindingFlags.NonPublic|BindingFlags.Instance);
就可以拿到某个类型的私有方法了 ^_~