自带委托Action Func
Action Func
可用invoke方法,也可以用圆括号代替。
Action返回空值void public void
Func委托
比较delegate Action Func
Action和Func都是基于delegate的特殊用法,Action的返回值类型是void,Func通过泛型可以自定义返回值类型,但型参只能有一种。可以接受0个至16个传入参数,无返回值
Func
Delegate至少0个参数,至多32个参数,可以无返回值,也可以指定返回值类型
class Program
{
static void Main(string[] args)
{
Calculator calculator = new Calculator();
Action action = new Action(calculator.Report);//不需要圆括号
calculator.Report();//直接调用
action.Invoke();//间接调用 委托.invoke()
action();//函数指针写法
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 = 100;
int z = 0;
z = func1.Invoke(x, y);
z = func1(x,y);//函数指针写法
Console.WriteLine(z);
z = func2.Invoke(x, y);
Console.WriteLine(z);
}
}
class Calculator
{
public void Report()
{
Console.WriteLine("i have 3 methods");
}
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;
}
}
自定义委托Delegate
委托是一种类型,继承自System.MulticastDelegate多播委托,此类型是特性类型,不能声明类型来继承,只能声明委托来自动继承—编译器限制。
public delegate double Calc(int x,int y); //声明
//double目标方法的返回值类型
//int x int y目标方法的参数
//嵌套类写在Program里面,最好加.
class Program
{
static void Main(string[] args)
{
Calculator calculator = new Calculator();
Calc calc1 = new Calc(calculator.Add);
//传入一个方法给委托Calc,方法的返回类型和参数需要和声明的一致
int x = 4;
int y = 2;
double z = 0;
z = calc1(x, y);
Console.WriteLine(z);
}
}
class Calculator
{
public double Add(int a, int b)
{
double result = a + b;
return result;
}
public double Sub(int a, int b)
{
double result = a - b;
return result;
}
public double Mul(int a, int b)
{
double result = a * b;
return result;
}
public double Div(int a, int b)
{
double result = a / b;
return result;
}
}
委托的一般使用
模板方法、回调方法
public delegate void OpenBoxFood(string ProductName);
class Program
{
static void Main(string[] args)
{
BoxProduct("Pizza",OpenBoxPizza);
BoxProduct("Switch",OpenBoxSwtich);
}
public static void BoxProduct(string productName, OpenBoxFood foodName)
{
foodName(productName);
}
public static void OpenBoxPizza(string productName)
{
Console.WriteLine(productName+" is very delicious!");
}
public static void OpenBoxSwtich(string productName)
{
Console.WriteLine(productName+" is also good!");
}
}
class Program
{
static void Main(string[] args)
{
var calculator = new Calculator();
// Action用于无形参无返回值的方法
Action action = new Action(calculator.Report);
calculator.Report();
action();
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(x, y);
Console.WriteLine(z);
z = func2(x, y);
Console.WriteLine(z);
}
}
class Calculator
{
public void Report()
{
Console.WriteLine("i have three methods");
}
public int Add(int a, int b)
{
return a + b;
}
public int Sub(int a, int b)
{
return a - b;
}
}
委托是一个类型需要创建实例,变量名=new 委托类型名(方法名)
public delegate int Calc_dele(int x ,int y);
class Program
{
static void Main(string[] args)
{
var calculator = new Calculator();
var calc1 = new Calc_dele(calculator.Add); //委托是一个类型需要创建实例,变量名=new 委托类型名(方法名)
Console.WriteLine(calc1(30,80));
}
}
class Calculator
{
public int Add(int a, int b)
{
return a + b;
}
public int Sub(int a, int b)
{
return a - b;
}
public int Mul(int a, int b)
{
return a * b;
}
}
class Program
{
static void Main(string[] args)
{
var productFactory = new ProductFactory();
Func<Product> func1 = new Func<Product>(productFactory.MakePizza);
Func<Product> func2 = new Func<Product>(productFactory.MakeToyCar);
var wrapFactory = new WrapFactory();
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; } //属性Name
}
class Box
{
public Product Product { get; set; } //属性,Product属于Product类,产品名称
}
class WrapFactory
{
// 模板方法,提高复用性
//包装工厂需要包装产品
//这里的委托类型的参数func 执行了MakePizza()这个方法,
//生产出了一个叫Pizza的产品,然后用盒子把产品包装起来
public Box WrapProduct(Func<Product> getProduct)
{
var box = new Box(); //新建实例box(空盒子)
Product product = getProduct.Invoke(); //第一次调用是MakePizza方法,Make Pizza()方法返回的是Product类型,将Pizza赋给产品名称
box.Product = product; //将产品名称赋给box里面的Product属性,封装起来(包装起来)
return box;//返回盒子
}
}
class ProductFactory
{
public Product MakePizza()
{
var product = new Product();
product.Name = "Pizza";
return product;
}
public Product MakeToyCar()
{
var product = new Product();
product.Name = "Toy Car";
return product;
}
}
委托的高级使用
单播委托
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace MulitDelegateAlbert
{
class Program
{
static void Main(string[] args)
{
Student student1 = new Student() { PenColor = ConsoleColor.Yellow,ID = 1 };
Student student2 = new Student() { PenColor = ConsoleColor.Red, ID = 2};
Student student3 = new Student() { PenColor = ConsoleColor.Green, ID = 3};
Action action = new Action(student1.DoHomework);
Action action1 = new Action(student2.DoHomework);
Action action2 = new Action(student3.DoHomework);
action.Invoke();
action1.Invoke();
action2.Invoke();
}
}
class Student
{
public int ID { get; set; }
public ConsoleColor PenColor { get; set; }
public void DoHomework()
{
for (int i = 0; i < 5; i++)
{
Console.ForegroundColor = this.PenColor;
Console.WriteLine("Student{0} is doing homework for {2} hours by pencolor{1}", ID, PenColor,i);
Thread.Sleep(500);
}
}
}
}
多播委托
一个委托封装多个方法,执行顺序按照封装的顺序来执行。
action += action1;
action += action2;
action.Invoke();
同步与异步(隐式异步调用)
同步调用
- 直接同步调用 方法名
- 间接同步调用 委托 代码见上面的单播委托、多播委托 委托.invoke()
异步调用
- 使用委托进行隐式异步调用 委托.BeginInvoke(null,null) 自动生成分支线程 容易造成资源冲突 ```csharp using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading;
namespace MulitDelegate { class Program { static void Main(string[] args) { Student student1 = new Student() { ID = 1, PencilColor = ConsoleColor.Red }; Student student2 = new Student() { ID = 2, PencilColor = ConsoleColor.Green }; Student student3 = new Student() { ID = 3, PencilColor = ConsoleColor.Blue };
Action action1 = new Action(student1.DoHomework);
Action action2 = new Action(student2.DoHomework);
Action action3 = new Action(student3.DoHomework);
action1.BeginInvoke(null, null);
action2.BeginInvoke(null, null);
action3.BeginInvoke(null, null);
for (int i = 0; i < 5; i++)
{
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("This is Main Thread of {0}",i);
Thread.Sleep(500);
}
Console.Read();
}
}
class Student
{
public int ID { get; set; }
public ConsoleColor PencilColor { get; set; }
public void DoHomework()
{
for (int i = 0; i < 5; i++)
{
Console.ForegroundColor = PencilColor;
Console.WriteLine("Student{0} is doing homework for {1} hours by pencil of {2}",ID,i,PencilColor);
Thread.Sleep(1000);
}
}
}
}
资源竞争:<br />
- 显示异步调用 Thread古老原始的方式
<a name="nEwut"></a>
##### Thread:
```csharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace MulitDelegate
{
class Program
{
static void Main(string[] args)
{
Student student1 = new Student() { ID = 1, PencilColor = ConsoleColor.Red };
Student student2 = new Student() { ID = 2, PencilColor = ConsoleColor.Green };
Student student3 = new Student() { ID = 3, PencilColor = ConsoleColor.Blue };
Thread thread1 = new Thread(new ThreadStart(student1.DoHomework));
Thread thread2 = new Thread(new ThreadStart(student2.DoHomework));
Thread thread3 = new Thread(new ThreadStart(student3.DoHomework));
thread1.Start();
thread2.Start();
thread3.Start();
for (int i = 0; i < 5; i++)
{
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("This is Main Thread of {0}",i);
Thread.Sleep(500);
}
Console.Read();
}
}
class Student
{
public int ID { get; set; }
public ConsoleColor PencilColor { get; set; }
public void DoHomework()
{
for (int i = 0; i < 5; i++)
{
Console.ForegroundColor = PencilColor;
Console.WriteLine("Student{0} is doing homework for {1} hours by pencil of {2}",ID,i,PencilColor);
Thread.Sleep(1000);
}
}
}
}
Task:
形式一:
Task task1 = new Task(new Action(stu1.DoHomework));
task1.Start();
形式二:
Task task1 = new Task(()=>
{
Action action1 = new Action(stu1.DoHomework);
});
task1.Start();
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace MulitDelegate
{
class Program
{
static void Main(string[] args)
{
Student student1 = new Student() { ID = 1, PencilColor = ConsoleColor.Red };
Student student2 = new Student() { ID = 2, PencilColor = ConsoleColor.Green };
Student student3 = new Student() { ID = 3, PencilColor = ConsoleColor.Blue };
Task task1 = new Task(new Action(student1.DoHomework));
Task task2 = new Task(new Action(student2.DoHomework));
Task task3 = new Task(new Action(student3.DoHomework));
task1.Start();
task3.Start();
try
{
Task task = new Task(() =>
{
Action action = new Action(student1.DoHomework);
});
}
catch (Exception)
{
throw;
}
Task task4 = new Task(() =>
{
student2.DoHomework();
});
Task task5 = new Task(() =>
{
student3.DoHomework();
});
task4.Start();
for (int i = 0; i < 5; i++)
{
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("This is Main Thread of {0}",i);
Thread.Sleep(500);
}
Console.Read();
}
}
class Student
{
public int ID { get; set; }
public ConsoleColor PencilColor { get; set; }
public void DoHomework()
{
for (int i = 0; i < 5; i++)
{
Console.ForegroundColor = PencilColor;
Console.WriteLine("Student{0} is doing homework for {1} hours by pencil of {2}",ID,i,PencilColor);
Thread.Sleep(1000);
}
}
}
}
设计模式
使用接口(Interface)取代一些对委托的使用:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace MulitDelegate
{
class Program
{
static void Main(string[] args)
{
IProductFactory pizzaFactory = new PizzaFactory();
IProductFactory toycarFactory = new ToyCarFactory();
var wrapFactory = new WrapFactory();
Box box1 = wrapFactory.WrapProduct(pizzaFactory);
Box box2 = wrapFactory.WrapProduct(toycarFactory);
Console.WriteLine(box1.Product.Name);
Console.WriteLine(box2.Product.Name);
Console.ReadLine();
}
}
interface IProductFactory
{
Product Make();
}
class PizzaFactory : IProductFactory
{
public Product Make()
{
var product = new Product();
product.Name = "Pizza";
return product;
}
}
class ToyCarFactory : IProductFactory
{
public Product Make()
{
var product = new Product();
product.Name = "Toy Car";
return product;
}
}
class Product
{
public string Name { get; set; } //属性Name
}
class Box
{
public Product Product { get; set; } //属性,Product属于Product类,产品名称
}
class WrapFactory
{
// 模板方法,提高复用性
//包装工厂需要包装产品
//这里的委托类型的参数func 执行了MakePizza()这个方法,
//生产出了一个叫Pizza的产品,然后用盒子把产品包装起来
public Box WrapProduct(IProductFactory productFactory)
{
var box = new Box(); //新建实例box(空盒子)
Product product = productFactory.Make(); //第一次调用是MakePizza方法,Make Pizza()方法返回的是Product类型,将Pizza赋给产品名称
box.Product = product; //将产品名称赋给box里面的Product属性,封装起来(包装起来)
return box;//返回盒子
}
}
}