文章目录
- 1.委托
- 委托的具体使用-魔板方法
- 回调方法【好莱坞方法】:通过委托类型的参数,传入主调方法的被调用方法,主调方法可以根据自己的逻辑决定调用这个方法还是不调用这个方法。【演员只用接听电话,如果通过,导演会打电话通知演员。】
- 同步调用
- 同步方法;使用委托对三个方法进行间接调用
- 多播委托,也是同步
- 使用Thread进行显示异步调用
- 使用Task进行显式异步调用
- 使用接口来取代委托
- C# 中提供的委托,Action和Func
- P30lambda表达式
- P29接口,反射,隔离,依赖注入
视频连接
1.委托
委托方法要和委托签名相匹配
// See https://aka.ms/new-console-template for more information
using ConsoleApp1.Model;
namespace ConsoleApp1
{
public class Program1
{
static void Main(string[] args) {
Calculator calculator = new Calculator();
calculator.Report();//直接调用
//Action委托
Action action = new Action(calculator.Report);
action.Invoke(); //使用委托进行间接调用
//Function委托
Func<double, double, double> func1 = new Func<double, double, double>(calculator.Add);
Func<double, double, double> func2 = new Func<double, double, double>(calculator.Sud);
double x = 200;
double y = 100;
double z = 0;
z=func1.Invoke(x,y);
Console.WriteLine(z);
z = func2.Invoke(x, y);
Console.WriteLine(z);
}
}
}
自定义委托方法Calc
// See https://aka.ms/new-console-template for more information
using ConsoleApp1.Model;
namespace ConsoleApp1
{
public delegate double Calc(double x, double y);
public class Program
{
static void Main(string[] args) {
Calculator calculator = new Calculator();
//委托的具体方法需要与委托的签名相匹配
Calc calc1 = new Calc(calculator.Add);
Calc calc2 = new Calc(calculator.Sud);
double x = 1.12;
double y = 2.23;
double res1=calc1(x,y);
double res2 = calc2(x, y);
Console.WriteLine(res1);
Console.WriteLine(res2);
}
}
}
委托的具体使用-魔板方法
// See https://aka.ms/new-console-template for more information
using ConsoleApp1.Model;
namespace ConsoleApp1
{
public 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;
}
}
}
回调方法【好莱坞方法】:通过委托类型的参数,传入主调方法的被调用方法,主调方法可以根据自己的逻辑决定调用这个方法还是不调用这个方法。【演员只用接听电话,如果通过,导演会打电话通知演员。】
// See https://aka.ms/new-console-template for more information
using ConsoleApp1.Model;
namespace ConsoleApp1
{
public 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}' is 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 = 20;
return product;
}
public Product MakeToyCar()
{
Product product = new Product();
product.Name = "Toy Car";
product.Price =100;
return product;
}
}
}
同步调用
// See https://aka.ms/new-console-template for more information
using ConsoleApp1.Model;
using System.ComponentModel;
namespace ConsoleApp1
{
public class Program
{
static void Main(string[] args)
{
Student1 student1 = new Student1() {ID=1,PenColor=ConsoleColor.Yellow };
Student1 student2 = new Student1() { ID =2, PenColor = ConsoleColor.Blue };
Student1 student3 = new Student1() { ID =3, PenColor = ConsoleColor.Green };
student1.DoWork();
student2.DoWork();
student3.DoWork();
for (int i=0;i<10 ;i++) {
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine("Main thread is working {0} hour.",i);
Thread.Sleep(1000);
}
}
}
class Student1 {
public string Name { get; set; }
public int ID { get; set; }
public ConsoleColor PenColor { get; set; }
public void DoWork() {
for (int i = 0; i < 4; i++)
{
Console.ForegroundColor = PenColor;
Console.WriteLine("ID is {0} thread is working----{1}hour.", ID,i);
Thread.Sleep(1000);
}
}
}
}
同步方法;使用委托对三个方法进行间接调用
Student1 student1 = new Student1() {ID=1,PenColor=ConsoleColor.Yellow };
Student1 student2 = new Student1() { ID =2, PenColor = ConsoleColor.Blue };
Student1 student3 = new Student1() { ID =3, PenColor = ConsoleColor.Green };
Action action1 = new Action(student1.DoWork);
Action action2 = new Action(student2.DoWork);
Action action3 = new Action(student3.DoWork);
action1.Invoke();
action2.Invoke();
action3.Invoke();
多播委托,也是同步
Action action1 = new Action(student1.DoWork);
Action action2 = new Action(student2.DoWork);
Action action3 = new Action(student3.DoWork);
action1+=action2;
action1+=action3;
action1.Invoke();
委托-使用委托可以进行隐式的异步调用。
使用Task.Run(() => action1.Invoke());代替原来的BeginInvoke方法。
// See https://aka.ms/new-console-template for more information
using ConsoleApp1.Model;
using System.ComponentModel;
namespace ConsoleApp1
{
public class Program
{
static void Main(string[] args)
{
Student1 student1 = new Student1() {ID=1,PenColor=ConsoleColor.Yellow };
Student1 student2 = new Student1() { ID =2, PenColor = ConsoleColor.Blue };
Student1 student3 = new Student1() { ID =3, PenColor = ConsoleColor.Green };
Action action1 = new Action(student1.DoWork);
Action action2 = new Action(student2.DoWork);
Action action3 = new Action(student3.DoWork);
//action1.BeginInvoke(null,null);
var task1=Task.Run(() => action1.Invoke());
// Console.WriteLine($"task1-action1------>{task1}");
var task2 = Task.Run(() => action2.Invoke());
// Console.WriteLine($"task2-action2----->{task2}");
var task3 = Task.Run(() => action3.Invoke());
// Console.WriteLine($"task3-action3----->{task3}");
for (int i=0;i<10 ;i++) {
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine("Main thread is working {0} hour.",i);
Thread.Sleep(1000);
}
}
}
class Student1 {
public string Name { get; set; }
public int ID { get; set; }
public ConsoleColor PenColor { get; set; }
public void DoWork() {
for (int i = 0; i < 4; i++)
{
Console.ForegroundColor = PenColor;
Console.WriteLine("Student {0} thread is working----{1}hour.", ID,i);
Thread.Sleep(1000);
}
}
}
}
使用Thread进行显示异步调用
static void Main(string[] args)
{
Student1 student1 = new Student1() {ID=1,PenColor=ConsoleColor.Yellow };
Student1 student2 = new Student1() { ID =2, PenColor = ConsoleColor.Blue };
Student1 student3 = new Student1() { ID =3, PenColor = ConsoleColor.Green };
//使用Thread进行显示异步调用
Thread t1 = new Thread(new ThreadStart(student1.DoWork));
Thread t2 = new Thread(new ThreadStart(student2.DoWork));
Thread t3 = new Thread(new ThreadStart(student3.DoWork));
t1.Start();
t2.Start();
t3.Start();
for (int i=0;i<10 ;i++) {
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine("Main thread is working {0} hour.",i);
Thread.Sleep(1000);
}
}
使用Task进行显式异步调用
//使用Task行显示异步调用
Task task1 = new Task(new Action(student1.DoWork));
Task task2 = new Task(new Action(student2.DoWork));
Task task3 = new Task(new Action(student3.DoWork));
task1.Start();
task2.Start();
task3.Start();
主线程和分支线程,互不等待,发生资源上的争抢。
使用接口来取代委托
// See https://aka.ms/new-console-template for more information
using ConsoleApp1.Model;
using System.ComponentModel;
namespace ConsoleApp1
{
//用接口代替委托
public class Program
{
static void Main(string[] args)
{
IProductfactory Pizzafactory = new Pizzafactory();
IProductfactory Toycarfactory = new ToyCarfactory();
//包装工厂生产盒子
WrapFactory wrapFactory = new WrapFactory();
Box pizzaBox=wrapFactory.WrapProduct(Pizzafactory);
Box totcarBox = wrapFactory.WrapProduct(Toycarfactory);
Console.WriteLine(pizzaBox.Product.Name);
Console.WriteLine(totcarBox.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;
}
}
//上面是新定义的两个工厂ToyCarfactory 和Pizzafactory
class Product
{
public string Name { get; set; }
public double Price { 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;
}
}
//下面的这个class Productfactory可以不不需要了
class Productfactory
{
public Product MakePizza()
{
Product product = new Product();
product.Name = "pizza";
product.Price = 20;
return product;
}
public Product MakeToyCar()
{
Product product = new Product();
product.Name = "Toy Car";
product.Price = 100;
return product;
}
}
}
C# 中提供的委托,Action和Func
Action适用于没有返回值的委托,Func适用于有返回值的委托。
可以使用var关键字缩短代码
用var action=new Action<string,int>(SayHello);代替Action<string,int> action=new Action<string,int>(SayHello);
Func适用于有返回值的委托
static void Main(string[] args){
Func<int,int,int> myFunc=new Func<int,int,int>(Add);
int res =myFunc(4,5);
Console.WriteLine(res);
}
static int Add(int a,int b){
return a+b;
}
}
Action适用于没有返回值的委托,
static void Main(string[] args){
Action action=new Action<string,int>(SayHello);
action("Tim",3);
}
static void SayHello(string name,int round){
for(int i=0;i<round;i++){
Console.WriteLine($"Helo {name}!");
}
}
P30lambda表达式
(int a, int b) => { return a + b; }
static void Main(string[] args)
{
//lambda表达式,匿名的
// Func<int, int, int> func = new Func<int, int, int>((int a, int b) => { return a + b; });
//lambda表达式,委托时简写
Func<int, int, int> func = (int a, int b) => { return a + b; };
int res=func(1, 2);
Console.WriteLine(res);
func = new Func<int, int, int>((int a, int b) => { return a *b; });
int res2 = func(1, 2);
Console.WriteLine(res2);
}
//lambda表达式,委托时简写,把lambda表达式赋值给委托类型的变量。
Func<int, int, int> func = (int a, int b) => { return a + b; };
泛型委托的类型推断
public class Program
{
static void Main(string[] args)
{
DoSomeCalc((a, b) => { return a + b; },1,2);
Console.WriteLine("handle result!");
}
static void DoSomeCalc<T>(Func<T,T,T>func,T x,T y) {
T res= func(x, y);
Console.WriteLine(res);
}
}