匿名函数
概念:没有名字的函数,一般情况下只调用一次。它的本质就是一个方法,虽然我们没有定义这个方法,但是编译器会把匿名函数编译成一个方法
public delegate void Del1();//无参数无返回值的委托public delegate void Del2(string name);//有参数无返回值的委托public delegate string Del3(string s,int n);//有参数有返回值的委托internal class Program{static void Main(string[] args){Del1 del1 = delegate (){Console.WriteLine("无参数无返回值的匿名函数");};del1.Invoke();Console.ReadKey();}}
我们可以使用lambda表达式更简洁地定义一个匿名函数
Del1 del1 = () => { Console.WriteLine("无参数无返回值的lambda表达式"); };del1.Invoke();//调用Console.ReadKey();
当lambda表达式中参数列表只有一个参数时,括号可以省略
Del2 del2 = msg => { Console.WriteLine("hello" + msg); };del2.Invoke("world" + "有参数无返回值的lambda表达式");Console.ReadKey();
匿名函数定义的参数列表的参数类型,是不能省略的
Del3 dle3 = (string s1, int n1) => { return "有参数有返回值的lambda表达式"; };string res = dle3.Invoke("1", 1);Console.WriteLine(res);
泛型委托
之前我们写的委托都是需要自己定义委托的参数和返回值,而.NET框架为我们封装了泛型委托框架,让我们不用再声明委托,可以直接使用。分别为Action委托,Func委托。
Action委托:
不带返回值的委托,可以有参数,也可以没有参数
Action action = () => { Console.WriteLine("无参无返回值的委托"); };action();//直接调用action.Invoke();//间接调用Action<string,int> action2 = (a,b)=> { Console.WriteLine("姓名为{0}的人,年龄为{1}",a,b); };action2.Invoke("张三",18);Console.ReadKey();
Func委托:
带返回值的委托
//如果Func尖括号里只有一个参数类型,就表示返回值就是这个类型Func<int> func = () => { return 100; };int a = func.Invoke();Console.WriteLine(a);//需要两个整数类型的参数,以及一个string类型的返回值Func<int, int, string> func2 = (c, d) => { Console.WriteLine(c); Console.WriteLine(d); return "hello world"; };string res = func2.Invoke(10, 20);Console.WriteLine(res);
使用委托进行窗体传值
1、先创建两个窗体对象,添加所需控件
2、当点击form1按钮时,将textbox里的值传递给form2
namespace 委托_窗体传值
{public partial class Form1 : Form{public Form1(){InitializeComponent();}private void button1_Click(object sender, EventArgs e){//创建一个form2对象,通过form2的构造函数将窗体1的文本框的值传递给窗体2Form2 form2 = new Form2(textBox1.Text.Trim());//将窗体2展示出来form2.Show();}}
}
namespace 委托_窗体传值
{public partial class Form2 : Form{public Form2(string msg)//窗体2的构造函数,每回创建窗体2对象的时候都会执行构造函数初始化。通过参数接收窗体一传递过来的值{InitializeComponent();textBox1.Text = msg;//将接收到的值展示到窗体2的文本框上}private void button1_Click(object sender, EventArgs e){}}
}
3、当点击form2的按钮时,将窗体2中的值传递给窗体1
public partial class Form2 : Form{string _msg;//字段存储窗体二收到的消息Action<string> _action;public Form2(string msg,Action<string> action)//窗体2的构造函数,每回创建窗体2对象的时候都会执行构造函数初始化。通过参数接收窗体一传递过来的值{InitializeComponent();//textBox1.Text = msg;//将接收到的值展示到窗体2的文本框上this._msg = msg;this._action = action;}private void button1_Click(object sender, EventArgs e){//调用ShowMsg,将值传递给窗体1this._action.Invoke(textBox1.Text.Trim());}private void Form2_Load(object sender, EventArgs e){//窗体加载的时候,把数据赋值给文本框textBox1.Text = this._msg;}}
namespace 委托_窗体传值
{public partial class Form1 : Form{public Form1(){InitializeComponent();}private void button1_Click(object sender, EventArgs e){//创建一个form2对象,通过form2的构造函数将窗体1的文本框的值传递给窗体2Form2 form2 = new Form2(textBox1.Text.Trim(),ShowMsg);//将窗体2展示出来form2.Show();}void ShowMsg(string msg){textBox1.Text = msg;}}
}
多播委托
概念:让一个委托对象,指向多个方法
internal class Program{public delegate void Del();static void Main(string[] args){Del del = M1;del += M2;del += M3;del += M4;del -= M5;del.Invoke();Console.ReadKey();}static void M1(){Console.WriteLine("我是M1");}static void M2(){Console.WriteLine("我是M2");}static void M3(){Console.WriteLine("我是M3");}static void M4(){Console.WriteLine("我是M4");}static void M5(){Console.WriteLine("我是M5");}}
运行结果
反射
概念:反射就是动态获取程序集中的元数据(提供程序集的类型信息)的功能
internal class Program{static void Main(string[] args){//Type//获取类型的类型:元数据//获取类型的Type有两种方式//1、创建了Person对象//Person p = new Person();//Type type = p.GetType();//2、没有创建Person对象Type type = typeof(Person); //typeof后面放的是数据类型,不能放对象//GetMembers()获取type反射出来所有的类型中的公共成员MemberInfo[] mi = type.GetMembers(BindingFlags.Instance|BindingFlags.NonPublic);foreach (var item in mi){Console.WriteLine(item.Name);}Console.ReadKey();}}class Person{public Person(){}private string _name;public int Age { get; set; }public void SayHi(){Console.WriteLine("实例方法");}public static void StaticSayHi(){Console.WriteLine("静态方法");}public Person(string name, int age){this._name = name;this.Age = age;}public Person(int age){this.Age = age;}}
反射程序集中的元数据
internal class Program{static void Main(string[] args){//1、先获取要反射数据的程序集//注意:就把ass这个程序集对象,当成是DLL类库Assembly ass = Assembly.LoadFile(@"C:\Users\ThinkPad\source\repos\DLL_Test\bin\Debug\DLL_Test.dll");//2、获取程序集中定义的数据类型/成员 GetTypes获取的成员包括public和internal修饰的//Type[] types = ass.GetTypes();//GetExportedTypes();获取所有被public修饰的成员//Type[] types = ass.GetExportedTypes();//foreach (var item in types)//{// Console.WriteLine(item.Name);//}//GetType():在类型的名字前面,必须加上命名空间Type type = ass.GetType("DLL_Test.Person");//class:类//Method:方法//field:字段//Property:属性//Instance:实例的//static:静态的//Assembly:程序集//Type:类型//Exported:公开的//Member:成员//Parameter:参数//Constructor:构造函数//GetMembers()获取类型中定义的所有公开成员//MemberInfo[] mi = type.GetMembers(BindingFlags.Instance | BindingFlags.NonPublic);//foreach (var item in mi)//{// Console.WriteLine(item.Name);//}//3、获取类型中定义的所有的方法//MethodInfo[] mi = type.GetMethods();//foreach (var item in mi)//{// Console.WriteLine(item.Name);// //Console.WriteLine(item.ReturnParameter.Name);// Console.WriteLine(item.ReturnType); //获取返回值的类型// Console.WriteLine("==============================");//}4、获取类型中定义的所有构造函数//ConstructorInfo[] ci = type.GetConstructors();//foreach (var item in ci)//{// Console.WriteLine(item.Name);// ParameterInfo[] pi = item.GetParameters();// foreach (var item2 in pi)// {// Console.WriteLine(item2.Name);// //获取参数类型// Console.WriteLine(item2.ParameterType);// Console.WriteLine("==============================================");// }//}//5、获取数据类型中定义的所有属性//PropertyInfo[] pi = type.GetProperties();//foreach (var item in pi)//{// Console.WriteLine(item.Name);//}//6、获取数据类型中定义的所有字段//FieldInfo[] fi = type.GetFields(BindingFlags.Instance|BindingFlags.NonPublic);//foreach (var item in fi)//{// Console.WriteLine(item.Name);//}//7、调用静态方法//MethodInfo[] mi = type.GetMethods(BindingFlags.Static | BindingFlags.Public); //foreach (var item in mi)//{// Console.WriteLine(item);//}//MethodInfo mi = type.GetMethod("StaticSayHi");调用参数1:表示实例对象,调用静态方法,可以不提供,给null值即可。参数2:表示方法的参数,必须以object数组的形式提供。//object res = mi.Invoke(null, new object[] { "world" });//Console.WriteLine(res);8、调用实例方法//MethodInfo mi = type.GetMethod("InstanceSayHi");动态的创建对象 CreateInstance帮我们执行构造函数,创建对象//object o = Activator.CreateInstance(type);//mi.Invoke(o, null);//9、调用重载方法 new Type[] { typeof(int), typeof(int) } 来匹配重载//MethodInfo mi = type.GetMethod("Add", new Type[] { typeof(int), typeof(int) });//object o = Activator.CreateInstance(type);//object res = mi.Invoke(o, new object[] { 1,1 });//Console.WriteLine(res);//10、调用构造函数ConstructorInfo ci = type.GetConstructor(new Type[] { });object o = ci.Invoke(null);Console.ReadKey();}}
反射相关的补充方法
internal class Program{static void Main(string[] args){//IsAssignableFrom: 后面的是否可以赋值给前面的//特点:既可以判断类,也可以判断接口//bool b = typeof(Person).IsAssignableFrom(typeof(Teacher));//bool b2 = typeof(I1).IsAssignableFrom(typeof(Teacher));//IsInstanceOfType:后面的对象,是否可以赋值给前面的类型Person p = new Person();Student s = new Student();Teacher t = new Teacher();//bool b3 = typeof(Person).IsInstanceOfType(p);//bool b4 = typeof(Person).IsInstanceOfType(s);//bool b5 = typeof(Person).IsInstanceOfType(t);//bool b6 = typeof(I2).IsInstanceOfType(t);//Console.WriteLine(b3);//Console.WriteLine(b4);//Console.WriteLine(b5);//Console.WriteLine(b6);//IsSubclassOf 跟接口没关系bool b = t.GetType().IsSubclassOf(typeof(I2));//Console.WriteLine(b);Console.WriteLine(typeof(Animal).IsAbstract);Console.WriteLine(typeof(Person).IsAbstract);Console.WriteLine(typeof(I2).IsAbstract);Console.ReadKey();}}class Person{}class Student : Person{ }abstract class Animal{ }interface I1{}interface I2 : I1 { }class Teacher : I2{ }
记事本插件开发
1、Form1
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Plug_in_Rule_DLL;
namespace _10_记事本插件开发
{public partial class Form1 : Form{public Form1(){InitializeComponent();}private void Form1_Load(object sender, EventArgs e){//程序加载的时候,读取指定目录下的插件//1、获取插件存储文件夹的路径string path = Assembly.GetExecutingAssembly().Location;path = Path.GetDirectoryName(path);path = Path.Combine(path, "Plug-in-Components");//2、读取该路径下所有的插件string[] files = Directory.GetFiles(path);//3、通过Assembly去加载程序集foreach (var file in files){//4、获取到当前循环到的插件程序集Assembly ass = Assembly.LoadFile(file);//5、获取程序集中的元数据//types:都是程序集中的数据类型。(类、接口、抽象类、委托、事件、.......)Type[] types = ass.GetExportedTypes();//6、对types做筛选foreach (var type in types){//筛选条件:1、实现了Plug_in_Rule接口的类 2、不能接口或者抽象类if (typeof(Plug_in_Rule).IsAssignableFrom(type) && !type.IsAbstract){//7、获取类型中的属性和方法//动态的创建插件的对象object o = Activator.CreateInstance(type);Plug_in_Rule pir = (Plug_in_Rule)o;//调用Name属性,赋值给MenustripToolStripItem tsi = menuStrip1.Items.Add(pir.Name);//8、给添加的小选项卡设置单击事件tsi.Click += Tsi_Click;//9、把pir接口,从Load方法中,传到Tsi_Click中tsi.Tag = pir;}}}//通过反射,获取程序集中的数据:Name ChangeText()//把Name加载到Menustrip菜单中,给菜单注册一个单击事件//单击的时候,执行ChangeText}//单击选项卡的时候,调用ChangeText()private void Tsi_Click(object sender, EventArgs e){//sender 事件是谁的,sender就是谁ToolStripItem tsi = sender as ToolStripItem;Plug_in_Rule p = (Plug_in_Rule)tsi.Tag;p.ChangeText(textBox1);}}
}
2、Plug_in_Rule 插件开发的接口规范
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace Plug_in_Rule_DLL
{/// <summary>/// 插件开发的接口规范/// </summary>public interface Plug_in_Rule{//接口中的只读属性,不是自动属性string Name { get; }//让插件开发人员,实现该方法,对文本的样式进行修改void ChangeText(TextBox textBox);}
}
3、Str_To_Lower 全部转小写功能
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Plug_in_Rule_DLL;
using System.Windows.Forms;
namespace Str_To_Lower_DLL
{public class Str_To_Lower : Plug_in_Rule{public string Name { get { return "全部转小写!!!!!"; } }public void ChangeText(System.Windows.Forms.TextBox textBox){textBox.Text = textBox.Text.ToLower();}}
}
4、Str_To_Upper 全部转大写功能
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Plug_in_Rule_DLL;
using System.Windows.Forms;
namespace Str_To_Upper_DLL
{/// <summary>/// 要拓展插件功能的人/// </summary>public class Str_To_Upper : Plug_in_Rule{public string Name { get { return "全部转大写!!!!"; } }public void ChangeText(System.Windows.Forms.TextBox textBox){textBox.Text = textBox.Text.ToUpper();}}
}