一、概念
泛型允许程序员在代码中将变量或参数的类型,先用[类型占位符]来代替,等到允许的时候再根据传入的[类]来代替
泛型是指带类型参数的类,而不是参数本身。
类、方法、结构、接口都可定义为泛型
可以定义多个参数 public class Person<T1,T2,...>
实例化一个引用参数类型的泛型,它的内存分配的大小是一样的;实例化一个值参数类型的泛型,它的内存分配的大小是不同的
1、泛型类
语法:
定义:public class List<T,F>{}
调用:List<T,F> list=new List<T,F>()
继承
继承一个泛型类的时候,必须为其传递泛型参数
约束
public class List<T>where T:new(){}
约束T的实例必须包含一个无参的构造函数
2、泛型方法
public void Test<k>(){}
三种用法:当方法参数、当返回值、在方法中实例化
二、反射
1、主要方法
//获取当前程序集对象集合
// Assembly[] ass = AppDomain.CurrentDomain.GetAssemblies();
//**************************反射获取成员
//1、获取当前正在运行的程序集( Assembly)对象
Assembly ass = this.GetType().Assembly;
//2、获取程序集中Dog类的类型(Type)对象
Type tDog = ass.GetType("反射.Dog");
//3、获取Dog类的name字段对象
FieldInfo finfo = tDog.GetField("name");
//4、获取Dog类的方法
MethodInfo minfo = tDog.GetMethod("ShootHi");
//**************************反射创建成员
//5、根据Dog的Type对象,实例化一个Dog对象
Dog d1 = Activator.CreateInstance(tDog) as Dog;
//6、使用Dog类的name字段对象,为d2实例的name字段赋值
finfo.SetValue(d1, "小白");
//7、使用Dog类的ShoutHi方法对象,执行d2实例的ShoutHi方法
string strRes = minfo.Invoke(d1, null).ToString();
获取类对象
Assembly ass = this.GetType().Assembly;
//通过类全名
Type tDog = ass.GetType("反射.Dog");
//获取当前程序集所有的公共的类
Type[] types = ass.GetExportedTypes();
//通过程序集获取所有的类型
Type[] typeAll = ass.GetTypes();
//通过类 直接获取对象
Type t2 = typeof(Dog);
//通过对象来获取类型对象
Type t3 = this.GetType();
Dog d3 = new Dog();
Type t4 = d3.GetType();
2、调用第三方程序集类
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;
namespace 记事本
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
MakeBtnByDLL(); ;
}
//读取程序集文件,并生成插件按钮
public void MakeBtnByDLL()
{
//1.加载路径
string strAssPath = this.GetType().Assembly.Location;
//2.获取程序集所在文件夹,并专成插件文件夹的路径
string strDirPath = System.IO.Path.GetDirectoryName(strAssPath) + "\\plugs";
//3.扫描插件文件夹里面所有的程序集文件,获取dll
string[] strDLLpaths = System.IO.Directory.GetFiles(strDirPath, "*.dll");
//4.遍历程序集文件路径并加载程序及到内存中
foreach (string strDll in strDLLpaths)
{
//4.1根据路径加载程序及文件到内存中
Assembly ass = Assembly.LoadFrom(strDll);
//4.2判断程序集中是否有插件类
//4.2.1或去插件程序集里的公有类
Type[] types = ass.GetExportedTypes();
//重要:获取插件接口类型对象
Type plugType = typeof(记事本插件interface.IPlug);
//4.2.2循环遍历插件程序集里的类型,判断是否实现了记事本插件接口
foreach (Type t in types)
{
//4.2.3判断t是否 实现了接口IPlug
if (plugType.IsAssignableFrom(t))
{
//重要:根据插件类型,创建插件类对象,并专程接口对象同一调用
记事本插件interface.IPlug iplugObj = Activator.CreateInstance(t) as 记事本插件interface.IPlug;
//4.3创建插件按钮
ToolStripMenuItem menuItem = new ToolStripMenuItem(t.Name);
this.tmsMenuItem.DropDownItems.Add(menuItem);
//位所有按钮的点击事件都绑定同一个方法
menuItem.Click += menuItem_Click;
//将接口对象存入按钮的tag属性
menuItem.Tag = iplugObj;
}
}
}
}
void menuItem_Click(object sender, EventArgs e)
{
ToolStripMenuItem menuItem = sender as ToolStripMenuItem;
//从按钮中取出对应的插件对象
记事本插件interface.IPlug iplug = menuItem.Tag as 记事本插件interface.IPlug;
//调用插件对象的处理文字方法,并重新设置给文本框
textBox1.Text = iplug.ProcessText(textBox1.Text);
}
}
}
第三方dll文件放置于程序执行路径的plugs内
三、特性/标签
作用:使程序可以动态获取类中的属性,注释等
运行时给程序员看的