委托是一个引用类型,其实它是一个类,保存方法的指针,它指向一个方法,当我们调用 委托的时候这个方法就立即被执行
using System;
namespace AdvancedDelegate
{
//公共委托 与方法类似
delegate void HelloDelegate(string msg);//定义委托
internal class Program
{
static void Main(string[] args)
{
//把方法,放进委托里面,给定参数进行调用方法
HelloDelegate helloDelegate = new HelloDelegate(Hello);//创建委托实列//委托指向的是一个方法
helloDelegate("你好委托!");//给委托传输字符串
helloDelegate.Invoke("你好委托!");
Console.ReadKey();
}
public static void Hello(string str)//在静态类中调用,定义为static
{
Console.WriteLine(str);
}
}
}
泛型:是把类型做到了通用
泛型委托
using System;
namespace AdvancedDelegate
{
delegate void GenericDelegate(T t);
public class GenericDelegate
{
public static void InvokeDelegate()
{
GenericDelegate genericDelegate = new GenericDelegate(Method1);
genericDelegate.Invoke("这个是泛型委托");
GenericDelegate genericDelegate2 = new GenericDelegate(Method2);
genericDelegate2.Invoke(99);
Action action = new Action(Method1);
action.Invoke("我是Action泛型委托的官方版本,不带有返回值");
Func func = new Func(Method3);
func.Invoke("我是带返回值的Func泛型委托,带有返回值的");
}
public static string InvokeDelegate1()
{
Func func = new Func(Method3);
return func.Invoke("我是带返回值的Func泛型委托,带有返回值的");
}
public static void Method1(string str)
{
Console.WriteLine(str);
}
public static void Method2(int num)
{
Console.WriteLine("我是泛型委托2:" + num);
}
public static string Method3(string str)
{
return str;
}
}
}
反射:是找出DLL文件里面的各种信息
特性:让我们的类,方法,属性,参数之类的产生了更多的功能。在不修改源码的情况下(打一个标签就生成了新功能,本质它就是我们AOP的另一种实现方式)
委托:有一只小白兔,有一天出去玩跑东跑西的,后找不到妈妈了,然后通过委托叔叔找到了妈妈
学习一个技术,主要是记住技术的主要特点
委托与冒泡排序
namespace AdvancedDelegate
{
public enum SortType
{
Ascending,
Descending
}
///
///
///
public static class SimpleSortSecond
{
public static void BubbleSort(int[] items, SortType sortType)
{
int i;
int j;
int temp;
if (items == null)
{
return;
}
for (i = items.Length - 1; i >= 0; i--)
{
for (j = 1; j <= i; j++)
{
bool swap = false;
switch (sortType)
{
case SortType.Ascending:
swap = items[j - 1] > items[j];
break;
case SortType.Descending:
swap = items[j - 1] < items[j];
break;
default:
break;
}
if (swap)
{
if (items[j - 1] > items[j])
{
temp = items[j - 1];
items[j - 1] = items[j];
items[j] = temp;
}
}
}
}
}
}
}
多播委托
【1】每一个委托都是继承自MulticastDelegate,每一个都是多播委托
【2】带返回值的多播委托,只返回最后一个方法的值
【3】多播委托,可以用+ -号,来操作方法的增加或者减少
【4】给委托传递相同方法时,生成的委托实例也是相同的(也是同一个委托)
using System;
namespace AdvancedDelegate
{
delegate void MulticastTest();
///
/// 多播委托
///
public class MulticastDelegateTest
{
public void Show()
{
//自定义委托
//MulticastTest multicastTest = new MulticastTest(MethodTest);
//multicastTest.Invoke();
Action action = new Action(MethodTest);
action = (Action)MulticastDelegate.Combine(action, new Action(MethodTest2));
action = (Action)MulticastDelegate.Combine(action, new Action(MethodTest3));
action = (Action)MulticastDelegate.Remove(action, new Action(MethodTest3));
action.Invoke();
//简写
Action action1 = MethodTest;
action1 += MethodTest2;
action1 += MethodTest3;
action1 -= MethodTest3;
action1.Invoke();
//委托还可以循环获取
foreach (Action item in action1.GetInvocationList())
{
item();
}
//带有返回值的委托
Func func = () => { return "我是Lambda方法"; };
func += () => { return "我是func1"; };
func += () => { return "我是func2"; };
func += () => { return "我是func3"; };
func -= () => { return "我是func3"; };//匿名方法,创建一个新的方法,所以返回还是【我是func3】每个匿名方法都不一样
func -= () => { return "我是func3"; };
func += GetTest;
func -= GetTest;//方法相同,会进行加+ -
string resoult = func();
Console.WriteLine(resoult);//带返回值的多播委托,只返回最后一个方法的值
}
public void MethodTest()
{
Console.WriteLine("我是方法MethodTest()");
}
public void MethodTest2()
{
Console.WriteLine("我是方法MethodTest2()");
}
public void MethodTest3()
{
Console.WriteLine("我是方法MethodTest3()");
}
public string GetTest()
{
return "我是方法GetTest()";
}
}
}
委托–事件:什么叫事件?事件就是委托的安全版本。第一点–在定义事件类的外部,他是不能使用=号来操作,只能用+=。第二点,在定义事件类的外部不能调用事件。另外事件就是委托的前面增减一个event关键字
using System;
namespace AdvancedEvent
{
delegate void StudentDelegate();//【1】定义一个委托
class Program
{
static void Main(string[] args)
{
EventFunction eventFunction = new EventFunction();
InvokeDefine invokeDefine = new InvokeDefine();
invokeDefine.StudentEvent += eventFunction.Student1;//【3】订阅事件
invokeDefine.StudentEvent += eventFunction.Student2;//事件中添加方法
invokeDefine.Invoke();
Console.ReadKey();
}
}
///
/// 定义事件和调用事件,一定要放在一个类里面
///
class InvokeDefine//【2】定义一个调用和定义事件的类【定义和调用放在一个类里面,是为了安全】
{
public event StudentDelegate StudentEvent;//委托的事件,不能放在类的外部
public void Invoke()
{
StudentEvent?.Invoke();//空引用运算符?.
//相当于
//if (StudentEvent != null)
//{
// StudentEvent.Invoke();
//}
}
}
class EventFunction//【4】订阅者
{
//实例化委托
public void Student1()
{
Console.WriteLine("我是一号学员");
}
public void Student2()
{
Console.WriteLine("我是二号学员");
}
}
}
WinForm里的事件
using System;
using System.Windows.Forms;
namespace EventDelegate
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("button1_Click");
}
private void button2_Click(object sender, EventArgs e)
{
MessageBox.Show("button2_Click");
}
private void button3_Click(object sender, EventArgs e)
{
MessageBox.Show("button3_Click");
}
}
}
this.button1.Location = new System.Drawing.Point(434, 101);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(75, 23);
this.button1.TabIndex = 0;
this.button1.Text = "button1";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
this.button1.Click += this.button2_Click;
this.button1.Click += this.button3_Click;
自定义标准事件
using System;
namespace StudentEvent
{
class Program
{
static void Main(string[] args)
{
Publisher publisher = new Publisher();
Subscriber subscriber = new Subscriber("Subscriber", publisher);
Subscriber2 subscriber2 = new Subscriber2("Subscriber2", publisher);
//调用引发事件的方法
publisher.DoSomething();
Console.ReadKey();
}
}
//事件发布者:事件的定义和调用 触发事件也可以写在这里
class Publisher//订阅者
{
public event EventHandler CustomEvent;//事件
public void DoSomething()
{
//调用之前可以在这里写一些其他的东西
OnCustomEvent(new CustomEventArgs("我是事件参数"));
}
//虚方法可以进行重新
//在受保护的虚方法中包装事件的调用,这样就允许派生类重新调用行为
protected virtual void OnCustomEvent(CustomEventArgs e)
{
//CustomEvent?.Invoke(this, e);
CustomEvent?.Invoke(this, e);
}
}
//事件参数
class CustomEventArgs : EventArgs
{
public CustomEventArgs(string message)
{
Message = message;
}
public string Message { get; set; }
}
//事件订阅:事件方法编写和订阅功能
class Subscriber
{
//订阅的动作要在这里面了,所以要传传过来发布者
public Subscriber(string str, Publisher publisher)
{
Str = str;
//订阅事件
publisher.CustomEvent += HanderCustomEvent;
}
private readonly string Str;
private void HanderCustomEvent(object sender, CustomEventArgs e)
{
//在这里做想做的事情
Console.WriteLine($"发布者:{sender.GetType()},订阅者:{Str},参数是:{e.Message}");
}
}
//订阅者可以无限
class Subscriber2
{
//订阅的动作要在这里面了,所以要传传过来发布者
public Subscriber2(string str, Publisher publisher)
{
Str = str;
//订阅事件
publisher.CustomEvent += HanderCustomEvent;
}
private readonly string Str;
private void HanderCustomEvent(object sender, CustomEventArgs e)
{
//在这里做想做的事情
Console.WriteLine($"发布者:{sender.GetType()},订阅者:{Str},参数是:{e.Message}");
}
}
}
示例代码
https://github.com/KuKuDePerson/CSharpAdvancedDelegate



