1. 委托定义
-
委托(delegate)是函数指针的升级版。委托是将方法作为方法的参数。
-
委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来传递。
-
一切皆地址。
- 变量(数据)是以某个地址为起点的一段内存中所存储的值;
- 函数(算法)是以某个地址为起点的一段内存中所存储的一组机器语言指令。
-
直接调用与间接调用
- 直接调用:通过函数名来调用函数,CPU通过函数名直接获得函数所在地址并开始执行,返回;
- 间接调用:通过函数指针来调用函数,CPU通过读取函数指针存储的值获得函数所在地址并开始执行,返回。
-
委托的声明原型:
delegate <函数返回类型><委托名>(<函数参数>)
public delegate void MyDelegate(string s);
委托MyDelegate可以被用于引用任何一个有单一string类型参数的方法,并返回void类型变量。
namespace Ex20210411_1
{
//委托:把方法作为方法的参数
public delegate void GreetingDelegate(string name);
class Program
{
private static void EnglishGreeting(string name)
{
Console.WriteLine("Hello," + name);
}
private static void ChineseGreeting(string name)
{
Console.WriteLine("你好," + name);
}
private static void SayHello(string name,GreetingDelegate GreetPeople)
{
GreetPeople(name);
}
static void Main(string[] args)
{
SayHello("Tom", EnglishGreeting);
SayHello("Mike", ChineseGreeting);
//间接调用委托
GreetingDelegate g1 = new GreetingDelegate(ChineseGreeting);//实例化委托
GreetingDelegate g2 = ChineseGreeting;
g1("张三");
//直接调用委托
EnglishGreeting("Lily");
}
}
}
2. 实例化委托
- 委托对象可以通过使用new关键字来创建,且与一个特定的方法有关。
- 当创建委托时,传递到new语句的参数就像方法调用一样书写,但是不带有参数。
- 委托是函数指针的“升级版”。
3. 内置委托
- Action是无返回值的泛型委托
- Action表示无参,无返回值的委托;
- Action<int,string> 表示有传入参数int,string,无返回值的委托;
- Action<int,string,bool> 表示有传入参数int,string,bool,无返回值的委托;
- Action<int,int,int,int> 表示有传入4个int型参数,无返回值的委托;
- Action至少0个参数,至多16个参数,无返回值。
- Func是有返回值的泛型委托
- Func 表示无参,返回值为int的委托;
- Func<object,string,int> 表示传入参数为object,string, 返回值为int的委托;
- Func<T1,T2,T3,int> 表示传入参数为T1,T2,T3,(泛型)返回值为int的委托;
- Func 至少有0个参数,至多16个参数,根据返回值泛型返回。必须有返回值,不可void.
//内置委托
namespace Ex20210411_2
{
class Program
{
static void Main(string[] args)
{
Greeting g1 = new Greeting();
Action action1 = new Action(g1.SayHelloEveryone);
Action<string> action2 = new Action<string>(g1.SayHello);
action1();
action2("Lily");
Caculate c1 = new Caculate();
Func<int, int, int> f1 = new Func<int, int, int>(c1.Add);
Func<int, int, int> f2 = new Func<int, int, int>(c1.Sub);
Console.WriteLine(f1(100, 200));
Console.WriteLine(f2(100, 200));
}
}
class Greeting
{
public void SayHelloEveryone()
{
Console.WriteLine("Hello,everyone.");
}
public void SayHello(string name)
{
Console.WriteLine("Hello," + name);
}
}
class Caculate
{
public int Add(int x, int y)
{
return x + y;
}
public int Sub(int x,int y)
{
return x - y;
}
}
}
4. 多播委托
- 委托对象可使用“➕”运算进行合并,当然也可以使用“➖”运算从合并的委托中移除组件委托;
- 只有相同类型的委托可以被合并;
- 调用多播委托时,方法按照添加的顺序被依次调用。
//多播委托
/*
委托对象可使用"+"运算符进行合并
"-"运算符可用于从合并的委托中移除组件委托。
只有相同类型的委托可被合并。
调用多播委托时,方法将按照添加的顺序被依次调用。*/
namespace Ex20210411_3
{
class Program
{
static void Main(string[] args)
{
Draw d1 = new Draw() { StuID = 1, PenColor = ConsoleColor.Red };
Draw d2 = new Draw() { StuID = 2, PenColor = ConsoleColor.Green };
Draw d3 = new Draw() { StuID = 3, PenColor = ConsoleColor.Blue };
Action action1 = new Action(d1.DrawPictrue);
Action action2 = new Action(d2.DrawPictrue);
Action action3 = new Action(d3.DrawPictrue);
action1 += action2;
action1 += action3;
action1();
action1 -= action3;
action1();
//action2();
//action3();
}
}
class Draw
{
public int StuID { get; set; }
public ConsoleColor PenColor { get; set; }
public void DrawPictrue()
{
Console.ForegroundColor = PenColor;
Console.WriteLine("Student{0} draw a cat.", StuID);
Console.WriteLine("Student{0} draw a dog.", StuID);
}
}
}
5. 隐式异步调用和显示异步调用 Task / BeginInvoke
class Program
{
static void Main(string[] args)
{
Student stu1 = new Student() { ID = 1, PenColor = ConsoleColor.Red };
Student stu2 = new Student() { ID = 1, PenColor = ConsoleColor.Green };
Student stu3 = new Student() { ID = 1, PenColor = ConsoleColor.Blue };
Action action1 = new Action(stu1.doHomework);
Action action2 = new Action(stu2.doHomework);
Action action3 = new Action(stu3.doHomework);
action1.BeginInvoke(null, null);
action2.BeginInvoke(null, null);
action3.BeginInvoke(null, null);
Task task1 = new Task(new Action(stu1.doHomework));
Task task2 = new Task(new Action(stu2.doHomework));
Task task3 = new Task(new Action(stu3.doHomework));
task1.Start();
task2.Start();
task3.Start();
for (int i = 0; i < 10; i++)
{
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("main thread");
Thread.Sleep(1000);
}
}
}
class Student
{
public int ID { get; set; }
public ConsoleColor PenColor { get; set; }
public void doHomework()
{
for (int i = 0; i < 5; i++)
{
Console.ForegroundColor = PenColor;
Console.WriteLine("{0} do work {1} hour(s)", ID, i + 1);
Thread.Sleep(1000);
}
}
}
6. 相关代码下载地址
链接:https://pan.baidu.com/s/19C_qxIT5uX7YAsmDU9Qckg
提取码:tnni