反射
->定义:通过一个程序集,获取程序集中包含的资源。动态获取程序集中的元数据的功能。
->智能提示用到的就是反射。
方法都封装在 AssemblyInof.cs类中
->好处:程序中只引用必须的程序集,减少程序的大小。
->当有接口的时候可以添加代码。。
Type类。。
1、获取类的Type的方式有两种Typeof()和对象.getType();
2、获取类后再获取类的方法。。type.getMehtod();type.getMethods();
3、获取类中的所有属性。type.GetProperties();
Assembly类。。。
1、获取程序集:Assembly asbl= assembly.LoadFile("strPath");
2、获取类库中的类的数组:Type[] tps= asbl.getTypes();
3、获取类的命名空间:tps[0].FullName
4、获取类库中第一个类的类名:Type tp= asbl.getType(tps[0].FullName);tp.Name;
Activator类。。。
1、动态创建一个类的对象:object obj=Activator.CreateInstance(tp);用于下面方法的调用。
2、获取类中的方法,MethodInfo method=asbl.GetMethod("方法名");
3、调用方法:method.Invoke(对象obj,方法所需的参数object类型,没有的时候为NULL);
几个常用的方法:
1、bool=type.IsAssionableFrom(type2);==>判断type是否接受type2类型变量的赋值。
type2能不能赋值给type,继承关系等。。
2、bool=type.IsInstanceOfType(type2);==>判断type2是否是type的实例(type可以是类,父类,接口)
判断括号里面是不是括号外的子类。
3、bool=type.IsSubclassOf(type2);==>判断type2是不是type的父类。。
4、bool=type.IsAbStract();==>判断是不是接口。。是不是抽象并且必须被重写。
2、插件接口写法:
1.获取程序集所有文件的目录中专门存储dll文件的Lib文件夹目录:
->Assembly.GetExecutingAssembly().Location;
Path.GetDirectoryName();
Path.Combine(name,"Lib");
2、获取目录下所有的dll文件:
Directory.GetFile(path,"*dll")
3、遍历所有文件的程序集。
4、获取所有的公共Type。。assembly.GetExpotedTypes();
5、获取接口的Type;typeof("接口");
6、遍历所有的公共Type集合。。
7、判断是否是接口的实例,IsAssignableFrom(item)&&item.IsAbStract
=>判断是否实现了接口。
8、创建实例。=>Activator.CreateInstance();
并且将object强转成接口的类型。
9、将插件的名字显示到下拉列表中。
10、给下拉列表注册一个事件。。
11、将接口对象存储到Tag中。
12、在事件中,获取到接口的对象
13、利用接口对象调用接口中预留的方法来对主程序进行修改。。
将sender强转成tag===再将tag强转成接口的实例对象。。。直接调用实例对象中的方法。
3、插件的写法:
1、创建一个类。添加引用,主程序给的接口。。添加命名空间
2、实现主程序的接口。
1 namespace _02记事本插件 2 { 3 public partial class FrmMain : Form 4 { 5 public FrmMain() 6 { 7 InitializeComponent(); 8 } 9 10 private void FrmMain_Load(object sender, EventArgs e) 11 { 12 //获取程序集中lib的目录 13 string path = Assembly.GetExecutingAssembly().Location; 14 path= Path.GetDirectoryName(path); 15 string name = Path.Combine(path, "Lib"); 16 //获取Lib文件中的所有dll文件 17 string[] files= Directory.GetFiles(name, "*.dll"); 18 19 foreach (string item in files) 20 { 21 //遍历文件中的所有类库,获取当前遍历到的类库中的所有类 22 Assembly ass = Assembly.LoadFile(item); 23 Type[] tps = ass.GetExportedTypes(); 24 25 26 //获取接口的类型 27 Type edit = typeof(IEdite); 28 //遍历当前类中的所有类 29 for (int i = 0; i < tps.Length; i++) 30 { 31 MessageBox.Show(tps[i].Name); 32 //判断当前类是不是继承了接口并且实现了接口 33 if(edit.IsAssignableFrom(tps[i])&&!tps[i].IsAbstract) 34 { 35 //创建一个接口的实例,用于后面的方法的调用 36 IEdite edi = Activator.CreateInstance(tps[i]) as IEdite; 37 38 39 //将名字添加下下拉列表中 40 ToolStripItem it= tsb.DropDownItems.Add(edi.Name); 41 //将接口的实例对象保存起来 42 it.Tag = edi; 43 //给下来列表注册一个点击的事件 44 it.Click += It_Click; 45 46 47 } 48 49 } 50 51 52 } 53 54 } 55 56 private void It_Click(object sender, EventArgs e) 57 { 58 //将传过来值强转成下拉列表的类型对象 59 ToolStripItem it= sender as ToolStripItem; 60 //将下拉列表类型转成接口类型对象 61 IEdite ie = it.Tag as IEdite; 62 //调用接口中的方法。 63 txtContent.Text= ie.ChangText(txtContent); 64 65 } 66 } 67 }
1 namespace MyEditeClass 2 { 3 public class MyEditeExn : IEdite 4 { 5 public string Name 6 { 7 get 8 { 9 return "小写转大写"; 10 } 11 } 12 13 public string ChangText(System.Windows.Forms.TextBox tb) 14 { 15 return tb.Text.ToUpper(); 16 } 17 } 18 }
原文:http://www.cnblogs.com/clcloveHuahua/p/5232605.html