Func委托
```c#
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
Calculator calculator = new Calculator();
Action action = new Action(calculator.Report);
calculator.Report();
action.Invoke();
Func<int, int, int> func1 = new Func<int, int, int>(calculator.Add);
Func<int, int, int> func2 = new Func<int, int, int>(calculator.Sub);
int x = 100;
int y = 200;
int z = 0;
z = func1.Invoke(x, y);
Console.WriteLine(z);
z = func2.Invoke(x, y);
Console.WriteLine(z);
}
}
class Calculator
{
public void Report()
{
Console.WriteLine("I have 3 method:");
}
public int Add(int a,int b)
{
int result = a + b;
return result;
}
public int Sub(int a, int b)
{
int result = a - b;
return result;
}
}
}
## 2、委托的声明(自定义委托)
### (1)委托是一种类( class ),类是数据类型所以委托也是一种数据类型
### (2)它的声名方式与般的类不同 ,主要是为 了照顾可读性和C/C+ +传统
### (3)注意声明委托的位置
- 避免写错地方结果声明成嵌套类型
### (4)委托与所封装的方法必需“类型兼容”
![image.png](https://s2.51cto.com/images/20210802/1627893583823783.png?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=)
```c#
namespace ConsoleApp2
{
public delegate double Calc(double x, double y);
class Program
{
static void Main(string[] args)
{
Calculator calculator = new Calculator();
Calc calc1 = new Calc(calculator.Add);
Calc calc2 = new Calc(calculator.Sub);
Calc calc3 = new Calc(calculator.Mul);
Calc calc4 = new Calc(calculator.Div);
double x = 100;
double y = 200;
double z = 0;
z = calc1(x, y);
Console.WriteLine(z);
z = calc2(x, y);
Console.WriteLine(z);
z = calc3(x, y);
Console.WriteLine(z);
z = calc4(x, y);
Console.WriteLine(z);
}
}
class Calculator
{
public double Add(double a, double b)
{
return a + b;
}
public double Sub(double a, double b)
{
return a - b;
}
public double Mul(double a, double b)
{
return a * b;
}
public double Div(double a, double b)
{
return a / b;
}
}
}
模板方法
```c#
namespace ConsoleApp2
{
public delegate double Calc(double x, double y);
class Program
{
static void Main(string[] args)
{
ProductFactory productFactory = new ProductFactory();
WrapFactory wrapFactory = new WrapFactory();
Func<Product> func1 = new Func<Product>(productFactory.MakePizza);
Func<Product> func2 = new Func<Product>(productFactory.MakeToyCar);
Box box1 = wrapFactory.WrapProduct(func1);
Box box2 = wrapFactory.WrapProduct(func2);
Console.WriteLine(box1.Product.Name);
Console.WriteLine(box2.Product.Name);
}
}
class Product
{
public string Name { get; set; }
}
class Box
{
public Product Product { get; set; }
}
class WrapFactory
{
public Box WrapProduct(Func<Product>getProduct)
{
Box box = new Box();
Product product = getProduct.Invoke();
box.Product = product;
return box;
}
}
class ProductFactory
{
public Product MakePizza()
{
Product product = new Product();
product.Name = "Pizza";
return product;
}
public Product MakeToyCar()
{
Product product = new Product();
product.Name = "Toy Car";
return product;
}
}
}
回调方法
```c#
namespace ConsoleApp2
{
public delegate double Calc(double x, double y);
class Program
{
static void Main(string[] args)
{
ProductFactory productFactory = new ProductFactory();
WrapFactory wrapFactory = new WrapFactory();
Func<Product> func1 = new Func<Product>(productFactory.MakePizza);
Func<Product> func2 = new Func<Product>(productFactory.MakeToyCar);
Logger logger = new Logger();
Action<Product> log = new Action<Product>(logger.Log);
Box box1 = wrapFactory.WrapProduct(func1,log);
Box box2 = wrapFactory.WrapProduct(func2,log);
Console.WriteLine(box1.Product.Name);
Console.WriteLine(box2.Product.Name);
}
}
class Logger
{
public void Log(Product product)
{
Console.WriteLine("Product ‘{0}‘ created at {1}. Price is {2}.",product.Name,DateTime.UtcNow,product.Price);
}
}
class Product
{
public string Name { get; set; }
public double Price { get; set; }
}
class Box
{
public Product Product { get; set; }
}
class WrapFactory
{
public Box WrapProduct(Func<Product>getProduct,Action<Product>logCallback)
{
Box box = new Box();
Product product = getProduct.Invoke();
if (product.Price>=50)
{
logCallback(product);
}
box.Product = product;
return box;
}
}
class ProductFactory
{
public Product MakePizza()
{
Product product = new Product();
product.Name = "Pizza";
product.Price = 12;
return product;
}
public Product MakeToyCar()
{
Product product = new Product();
product.Name = "Toy Car";
product.Price = 100;
return product;
}
}
}
```c#
namespace ConsoleApp2
{
public delegate double Calc(double x, double y);
class Program
{
static void Main(string[] args)
{
Student stu1 = new Student() { ID = 1, PenColor = ConsoleColor.Yellow };
Student stu2 = new Student() { ID = 2, PenColor = ConsoleColor.Green };
Student stu3 = new Student() { ID = 3, PenColor = ConsoleColor.Red };
Action action1 = new Action(stu1.DoHomework);
Action action2 = new Action(stu2.DoHomework);
Action action3 = new Action(stu3.DoHomework);
action1 += action2;
action1 += action3;
action1.Invoke();
}
}
class Student
{
public int ID { get; set; }
public ConsoleColor PenColor { get; set; }
public void DoHomework()
{
for (int i = 1; i < 5; i++)
{
Console.ForegroundColor = this.PenColor;
Console.WriteLine("Student{0} doing homework{1} hours(s).",this.ID,i);
Thread.Sleep(1000);
}
}
}
}
### (2)隐式异步调用
- 同步与异步的简介
- 中英文的语言差异
- 同步:你做完了我(在你的基础上)接着做
- 异步:咱们两个同时做(相当于汉语中的“同步进行")
### (3)同步调用与异步调用的对比
- 每一个运行的程序是一个进程 ( process )
- 每个进程可以有一一个或者多个线程( thread )
- 同步调用是在同一线程内
- 异步调用的底层机理是多线程
- 串行=同步=单线程, 并行=异步=多线程
### (4)隐式多线程 V.S 显式多线程
- 直接同步调用:使用方法名
```c#
namespace ConsoleApp2
{
public delegate double Calc(double x, double y);
class Program
{
static void Main(string[] args)
{
Student stu1 = new Student() { ID = 1, PenColor = ConsoleColor.Yellow };
Student stu2 = new Student() { ID = 2, PenColor = ConsoleColor.Green };
Student stu3 = new Student() { ID = 3, PenColor = ConsoleColor.Red };
stu1.DoHomework();
stu2.DoHomework();
stu3.DoHomework();
for (int i = 0; i < 10; i++)
{
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine("Main thread{0}",i);
Thread.Sleep(1000);
}
}
}
class Student
{
public int ID { get; set; }
public ConsoleColor PenColor { get; set; }
public void DoHomework()
{
for (int i = 1; i < 5; i++)
{
Console.ForegroundColor = this.PenColor;
Console.WriteLine("Student{0} doing homework{1} hours(s).",this.ID,i);
Thread.Sleep(1000);
}
}
}
}
间接同步调用:使用单播/多播委托的Invoke方法
```c#
namespace ConsoleApp2
{
public delegate double Calc(double x, double y);
class Program
{
static void Main(string[] args)
{
Student stu1 = new Student() { ID = 1, PenColor = ConsoleColor.Yellow };
Student stu2 = new Student() { ID = 2, PenColor = ConsoleColor.Green };
Student stu3 = new Student() { ID = 3, PenColor = ConsoleColor.Red };
Action action1 = new Action(stu1.DoHomework);
Action action2 = new Action(stu2.DoHomework);
Action action3 = new Action(stu3.DoHomework);
action1.Invoke();
action2.Invoke();
action3.Invoke();
}
}
class Student
{
public int ID { get; set; }
public ConsoleColor PenColor { get; set; }
public void DoHomework()
{
for (int i = 1; i < 5; i++)
{
Console.ForegroundColor = this.PenColor;
Console.WriteLine("Student{0} doing homework{1} hours(s).",this.ID,i);
Thread.Sleep(1000);
}
}
}
}
隐式异步调用:使用委托的Beginlnvoke
```c#
namespace ConsoleApp2
{
public delegate double Calc(double x, double y);
class Program
{
static void Main(string[] args)
{
Student stu1 = new Student() { ID = 1, PenColor = ConsoleColor.Yellow };
Student stu2 = new Student() { ID = 2, PenColor = ConsoleColor.Green };
Student stu3 = new Student() { ID = 3, PenColor = ConsoleColor.Red };
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) ;
for (int i = 1; i < 10; i++)
{
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine("Main thread{0}.", i);
Thread.Sleep(1000);
}
}
}
class Student
{
public int ID { get; set; }
public ConsoleColor PenColor { get; set; }
public void DoHomework()
{
for (int i = 1; i < 5; i++)
{
Console.ForegroundColor = this.PenColor;
Console.WriteLine("Student{0} doing homework{1} hours(s).",this.ID,i);
Thread.Sleep(1000);
}
}
}
}
显式异步调用:使用Thread或Task
```c#
namespace ConsoleApp2
{
public delegate double Calc(double x, double y);
class Program
{
static void Main(string[] args)
{
Student stu1 = new Student() { ID = 1, PenColor = ConsoleColor.Yellow };
Student stu2 = new Student() { ID = 2, PenColor = ConsoleColor.Green };
Student stu3 = new Student() { ID = 3, PenColor = ConsoleColor.Red };
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 = 1; i < 10; i++)
{
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine("Main thread{0}.", i);
Thread.Sleep(1000);
}
}
}
class Student
{
public int ID { get; set; }
public ConsoleColor PenColor { get; set; }
public void DoHomework()
{
for (int i = 1; i < 5; i++)
{
Console.ForegroundColor = this.PenColor;
Console.WriteLine("Student{0} doing homework{1} hours(s).",this.ID,i);
Thread.Sleep(1000);
}
}
}
Java完全地使用接口取代了委托的功能,即Java没有与C#中委托相对应的功能实体
```c#
namespace ConsoleApp2
{
public delegate double Calc(double x, double y);
class Program
{
static void Main(string[] args)
{
IProductFactory pizzaFactory = new PizzaFactory();
IProductFactory toycarFactory = new ToyCarFactory();
WrapFactory wrapFactory = new WrapFactory();
Box box1 = wrapFactory.WrapProduct(pizzaFactory);
Box box2 = wrapFactory.WrapProduct(toycarFactory);
Console.WriteLine(box1.Product.Name);
Console.WriteLine(box2.Product.Name);
}
}
interface IProductFactory
{
Product Make();
}
class PizzaFactory : IProductFactory
{
public Product Make()
{
Product product = new Product();
product.Name = "Pizza";
return product;
}
}
class ToyCarFactory : IProductFactory
{
public Product Make()
{
Product product = new Product();
product.Name = "Toy Car";
return product;
}
}
class Product
{
public string Name { get; set; }
}
class Box
{
public Product Product { get; set; }
}
class WrapFactory
{
public Box WrapProduct(IProductFactory productFactory)
{
Box box = new Box();
Product product = productFactory.Make();
box.Product = product;
return box;
}
}
}
原文:https://blog.51cto.com/u_15296868/3258564