C/C++中的函数指针实例:
typedef int (*Calc)(int a, int b); //这里必须加括号
int Add(int a, int b)
{
return a + b;
}
int Sub(int a, int b)
{
return a - b;
}
int main()
{
int x = 100;
int y = 200;
int z = 0;
Calc funcPoint1 = &Add;
Calc funcPoint2 = ⋐
z = funcPoint1(x, y);
cout << z << endl;
z = funcPoint2(x, y);
cout << z << endl;
}
class Program
{
static void Main(string[] args)
{
Calculator c = new Calculator();
//Action委托:没有返回参数
Action action = new Action(c.PrintInfo);
c.PrintInfo();
action.Invoke();
action();
//Func委托:有返回参数
Func f = new Func(c.Add);
Func f2 = new Func(c.Sub);
Console.WriteLine(f(1, 2));
Console.WriteLine(f.Invoke(1, 2));
Console.WriteLine(f2(1, 2));
Console.WriteLine(f2.Invoke(1, 2));
}
}
class Calculator
{
public void PrintInfo()
{
Console.WriteLine("this class has 3 methods");
}
public int Add(int a, int b)
{
return a + b;
}
public int Sub(int a, int b)
{
return a - b;
}
}
class Program
{
static void Main(string[] args)
{
Action action = new Action(SayHello);
action("Tim");
}
static void SayHello(string name)
{
Console.WriteLine($"Hello, {name1}!");
}
}
//可以用var关键字来缩短代码:
class Program
{
static void Main(string[] args)
{
var action = new Action(SayHello);
action("Tim");
}
static void SayHello(string name, int rount)
{
for(int i=0; i
//复杂麻烦的写法
string str1 = "my name is " + name + ",my age is " + age + ".";
//使用Format的写法
string str2 = string.Format("my name is {0},my age is {1}.", name, age);
//使用$语法糖的写法
string str3 = $"my name is {name},my age is {age}.";
public delegate double Calc(double x, double y);
class Program
{
static void Main(string[] args)
{
Calculator calculator = new Calculator();
double x = 200;
double y = 100;
double z;
Calc calc1 = new Calc(calculator.Add);
Calc calc2 = new Calc(calculator.Sub);
Calc calc3 = new Calc(calculator.Mul);
Calc calc4 = new Calc(calculator.Div);
z = calc1(x, y);
Console.WriteLine(z);
z = calc2.Invoke(x, y);
Console.WriteLine(z);
z = calc3.Invoke(x, y);
Console.WriteLine(z);
z = calc4.Invoke(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;
}
}
class Program
{
static void Main(string[] args)
{
ProductFactory pf = new ProductFactory();
WrapFactory wf = new WrapFactory();
Func func1 = new Func(pf.MakePizza);
Func func2 = new Func(pf.MakeToyCar);
Box box1 = wf.WrapProduct(func1);
Box box2 = wf.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 getProduct)
{
Box box = new Box();
box.Product = getProduct.Invoke();
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;
}
}
class Program
{
static void Main(string[] args)
{
ProductFactory pf = new ProductFactory();
WrapFactory wf = new WrapFactory();
Func func1 = new Func(pf.MakePizza);
Func func2 = new Func(pf.MakeToyCar);
Logger logger = new Logger();
Action action = new Action(logger.log);
Box box1 = wf.WrapProduct(func1, action);
Box box2 = wf.WrapProduct(func2, action);
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 int Price { get; set; }
}
class Box
{
public Product Product { get; set; }
}
class WrapFactory
{
public Box WrapProduct(Func getProduct, Action logCallback)
{
Box box = new Box();
Product product = getProduct.Invoke();
if(product.Price>=50)
{
logCallback.Invoke(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;
}
}
class Program
{
static void Main(string[] args)
{
Student stu1 = new Student() { ID=1, PenColor = ConsoleColor.Yellow};
Student stu2 = new Student() { ID=1, PenColor = ConsoleColor.Green};
Student stu3 = new Student() { ID=1, 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();
//多播委托
action1 += action2;
action1 += action3;
action1.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} doing homework {1} hour(s).", this.ID, i);
Thread.Sleep(1000);
}
}
}
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 = 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 = 0; i < 5; i++)
{
Console.ForegroundColor = this.PenColor;
Console.WriteLine("Student {0} doing homework {1} hour(s).", this.ID, i);
Thread.Sleep(1000);
}
}
}
注:ctrl+. 给没有定义命名空间的类添加命名空间
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};
//显式异步调用
Thread thread1 = new Thread(new ThreadStart(stu1.DoHomeWork));
Thread thread2 = new Thread(new ThreadStart(stu2.DoHomeWork));
Thread thread3 = new Thread(new ThreadStart(stu3.DoHomeWork));
thread1.Start();
thread2.Start();
thread3.Start();
//使用task显式异步调用
Action action1 = new Action(stu1.DoHomeWork);
Action action2 = new Action(stu2.DoHomeWork);
Action action3 = new Action(stu3.DoHomeWork);
Task task1 = new Task(action1);
Task task2 = new Task(action2);
Task task3 = new Task(action3);
task1.Start();
task2.Start();
task3.Start();
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 = 0; i < 5; i++)
{
Console.ForegroundColor = this.PenColor;
Console.WriteLine("Student {0} doing homework {1} hour(s).", this.ID, i);
Thread.Sleep(1000);
}
}
}
可以使用接口来取代委托
以上面的回调方法中的例子作为改进:
class Program
{
static void Main(string[] args)
{
IProductFactory pizzaFactory = new PizzaFactory();
IProductFactory toycarFactory = new ToycarFactory();
WrapFactory wf = new WrapFactory();
Box box1 = wf.WrapProduct(pizzaFactory);
Box box2 = wf.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";
product.Price = 12;
return product;
}
}
class ToycarFactory : IProductFactory
{
public Product Make()
{
Product product = new Product();
product.Name = "Toy Car";
product.Price = 100;
return product;
}
}
class Product
{
public string Name { get; set; }
public int 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 Program
{
static void Main(string[] args)
{
MyDele dele1 = new MyDele(M1);
Student stu = new Student();
//dele1 += stu.SayHello;
//同上
dele1 += (new Studnet()).SayHello;
//dele1.Invoke();
//同上,与上面相比下面直接调用方法更常用。
dele1();
}
static void M1()
{
Console.Write("M1 is called");
}
class Student{
public void SayHello(){
Concole.WriteLine("Hello, I'm a student!");
}
}
delegate void MyDele();
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DelegateExample
{
class Program
{
static void Main(string[] args)
{
MyDele myDele = new MyDele(Add);
int addRed = myDele(2, 4);
Console.WriteLine(addRed);
MyDele myDele2 = new MyDele(Mul);
double mulRed = myDele2(2.2, 2.2);
Console.WriteLine(mulRed);
//查看委托是否是类
Console.WriteLine(myDele.GetType().IsClass);
}
static int Add(int x, int y)
{
return x + y;
}
static double Mul(double x, double y)
{
return x * y;
}
}
delegate T MyDele(T a, T b);
}
微软把这种经由事件发送出来的与事件本身相关的数据称为:事件参数
把根据通知和事件参数来采取行动的这种行为称为响应事件或处理事件。处理事件时具体所做的事情就叫做事件处理器。
class Program
{
static void Main(string[] args)
{
//timer: 事件的拥有者
Timer timer = new Timer();
timer.Interval = 1000;
// boy和girl: 事件的响应者
Boy boy = new Boy();
//timer.Elapsed: 事件成员; boy.Action: 事件处理器;+=: 事件订阅
timer.Elapsed += boy.Action;
Girl girl = new Girl();
timer.Elapsed += girl.Action;
//timer.Enabled = true;
timer.Start();
Console.ReadLine();
}
}
class Boy
{
internal void Action(object sender, ElapsedEventArgs e)
{
Console.WriteLine("jump");
}
}
class Girl
{
internal void Action(object sender, ElapsedEventArgs e)
{
Console.WriteLine("Sing");
}
}
class Program
{
static void Main(string[] args)
{
//form: 事件拥有者
Form form = new Form();
//controller: 事件响应者
Controller controller = new Controller(form);
form.ShowDialog();
}
}
class Controller
{
private Form form;
public Controller(Form form)
{
this.form = form;
//this.form.Click: 事件; +=: 事件订阅
this.form.Click += this.FormClicked;
}
//FormClicked:事件处理器
private void FormClicked(object sender, EventArgs e)
{
this.form.Text = DateTime.Now.ToString();
}
}
class Program
{
static void Main(string[] args)
{
//form: 事件拥有者和响应者
MyForm form = new MyForm();
form.Click += form.FormClicked;
form.ShowDialog();
}
}
class MyForm : Form
{
internal void FormClicked(object sender, EventArgs e)
{
this.Text = DateTime.Now.ToString();
}
}
class Program
{
static void Main(string[] args)
{
//form: 事件拥有者和响应者
MyForm form = new MyForm();
form.ShowDialog();
}
}
this Form: 响应者
class MyForm : Form
{
private TextBox textBox;
private Button button;
public MyForm()
{
this.textBox = new TextBox();
//this.button: 拥有者
this.button = new Button();
this.Controls.Add(this.textBox);
this.Controls.Add(this.button);
this.button.Click += this.ButtonClicked;
this.button.Text = "say hello";
this.button.Top = 50;
}
public void ButtonClicked(object sender, EventArgs e)
{
this.textBox.Text = "Hello World!!!!!!!!!!!!!!!!!!";
}
}
namespace EventWindowsForms
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
//button2. 方法2. 手动订阅
this.button2.Click += buttonClick;
//button3. 方法3.委托
this.button3.Click += new EventHandler(buttonClick);
//button4. 方法4. 旧式委托
this.button4.Click += delegate (object sender, EventArgs e)
{
this.myTextBox.Text = "button4Clicked!";
};
//button5. 方法5. lambda表达式
this.button5.Click += (sender, e) =>
{
this.myTextBox.Text = "button5Clicked!";
};
}
//button1. 方法1.直接在设计中双击click自动生成订阅
private void buttonClick(object sender, EventArgs e)
{
if(sender==button1)
{
this.myTextBox.Text = "hello!";
}
if(sender==button2)
{
this.myTextBox.Text = "world!";
}
if(sender==button3)
{
this.myTextBox.Text = "My.Okey!";
}
}
}
}
namespace FullFormOfEvent
{
class Program
{
static void Main(string[] args)
{
Customer customer = new Customer();
Waiter waiter = new Waiter();
customer.Order += waiter.Action;
//一定是事件拥有者的内部逻辑触发了该事件
customer.Action();
customer.PayThisBill();
}
}
public class OrderEventArgs:EventArgs
{
public string DishName { get; set; }
public string Size { get; set; }
}
//声明委托类型 为声明的order事件用的
//当一个委托专门用来声明事件时,名称一般为事件名+EventHandler
public delegate void OrderEventHandler(Customer customer, OrderEventArgs e);
public class Customer
{
//声明一个委托类型的字段 引用事件处理器的
private OrderEventHandler orderEventHandler;
public event OrderEventHandler Order
{
add
{
this.orderEventHandler += value;
}
remove
{
this.orderEventHandler -= value;
}
}
public double Bill { get; set; }
public void PayThisBill()
{
Console.WriteLine("I will pay ${0}.", this.Bill);
}
//事件要通过委托来做一个约束,这个委托
//既规定了事件发送什么消息给事件的响应者
//也规定了事件的响应者能收到什么样的消息
//事件响应者的事件处理器必须能够跟约束匹配上,才能订阅事件
//当事件的响应者向事件的拥有者提供了能够匹配这个事件的事件处理器之后,
//需要将此处理器保存或记录下来,能够记录或引用方法的任务只有
//引用委托的实例才能够做到。
//事件这种成员,无论从表层约束上来讲,还是从底层实现来讲,都依赖委托类型
public void WalkIn()
{
Console.WriteLine("Walk into the restaurant.");
}
public void SitDown()
{
Console.WriteLine("Sit down.");
}
public void Think()
{
for (int i = 0; i < 5; i++)
{
Console.WriteLine("Let me think。。。");
Thread.Sleep(1000);
}
if(this.orderEventHandler!=null)
{
OrderEventArgs e = new OrderEventArgs();
e.DishName = "Kongpao Chicken";
e.Size = "large";
this.orderEventHandler.Invoke(this, e);
}
}
public void Action()
{
Console.ReadLine();
this.WalkIn();
this.SitDown();
this.Think();
}
}
public class Waiter
{
internal void Action(Customer customer, OrderEventArgs e)
{
Console.WriteLine("I will serve you the dish - {0}.", e.DishName);
double price = 10;
switch (e.Size)
{
case "small":
price = price * 0.5;
break;
case "large":
price = price * 1.5;
break;
default:
break;
}
customer.Bill += price;
}
}
}
只修改了两个部分
namespace FullFormOfEvent
{
class Program
{
static void Main(string[] args)
{
Customer customer = new Customer();
Waiter waiter = new Waiter();
customer.Order += waiter.Action;
//一定是事件拥有者的内部逻辑触发了该事件
customer.Action();
customer.PayThisBill();
}
}
public class OrderEventArgs:EventArgs
{
public string DishName { get; set; }
public string Size { get; set; }
}
//声明委托类型 为声明的order事件用的
//当一个委托专门用来声明事件时,名称一般为事件名+EventHandler
public delegate void OrderEventHandler(Customer customer, OrderEventArgs e);
public class Customer
{
// 修改1
public event OrderEventHandler Order;
public double Bill { get; set; }
public void PayThisBill()
{
Console.WriteLine("I will pay ${0}.", this.Bill);
}
public void WalkIn()
{
Console.WriteLine("Walk into the restaurant.");
}
public void SitDown()
{
Console.WriteLine("Sit down.");
}
public void Think()
{
for (int i = 0; i < 5; i++)
{
Console.WriteLine("Let me think。。。");
Thread.Sleep(1000);
}
//修改2
//和详细声明相比,现在用了一个事件的名字取代了过去这个字段上的名字
//之前的委托类型字段还在,只不过没有出现在代码中
if(this.Order!=null)
{
OrderEventArgs e = new OrderEventArgs();
e.DishName = "Kongpao Chicken";
e.Size = "large";
this.Order.Invoke(this, e);
}
}
public void Action()
{
Console.ReadLine();
this.WalkIn();
this.SitDown();
this.Think();
}
}
public class Waiter
{
internal void Action(Customer customer, OrderEventArgs e)
{
Console.WriteLine("I will serve you the dish - {0}.", e.DishName);
double price = 10;
switch (e.Size)
{
case "small":
price = price * 0.5;
break;
case "large":
price = price * 1.5;
break;
default:
break;
}
customer.Bill += price;
}
}
}
namespace FullFormOfEvent
{
class Program
{
static void Main(string[] args)
{
Customer customer = new Customer();
Waiter waiter = new Waiter();
customer.Order += waiter.Action;
//一定是事件拥有者的内部逻辑触发了该事件
customer.Action();
customer.PayThisBill();
}
}
public class OrderEventArgs:EventArgs
{
public string DishName { get; set; }
public string Size { get; set; }
}
public class Customer
{
//省去了委托类型的声明,而是使用了通用的EventHandler
public event EventHandler Order;
public double Bill { get; set; }
public void PayThisBill()
{
Console.WriteLine("I will pay ${0}.", this.Bill);
}
public void WalkIn()
{
Console.WriteLine("Walk into the restaurant.");
}
public void SitDown()
{
Console.WriteLine("Sit down.");
}
public void Think()
{
for (int i = 0; i < 5; i++)
{
Console.WriteLine("Let me think。。。");
Thread.Sleep(1000);
}
//和详细声明相比,现在用了一个事件的名字取代了过去这个字段上的名字
//之前的委托类型字段还在,只不过没有出现在代码中
if(this.Order!=null)
{
OrderEventArgs e = new OrderEventArgs();
e.DishName = "Kongpao Chicken";
e.Size = "large";
this.Order.Invoke(this, e);
}
}
public void Action()
{
Console.ReadLine();
this.WalkIn();
this.SitDown();
this.Think();
}
}
public class Waiter
{
internal void Action(Object sender, EventArgs e)
{
Customer customer = sender as Customer;
OrderEventArgs orderInfo = e as OrderEventArgs;
Console.WriteLine("I will serve you the dish - {0}.", orderInfo.DishName);
double price = 10;
switch (orderInfo.Size)
{
case "small":
price = price * 0.5;
break;
case "large":
price = price * 1.5;
break;
default:
break;
}
customer.Bill += price;
}
}
}
是匿名和inline方法
//lambda表达式:方法1
Func func = new Func((int a, int b)=> { return a + b; });
int res = func(3, 5);
Console.WriteLine($"a+b={res}");
//方法2
func = new Func((x, y) => { return x * y; });
res = func(3, 5);
Console.WriteLine($"a*b={res}");
//方法3 最常用
func = (x, y) => { return x - y; };
res = func(3, 5);
Console.WriteLine($"a-b={res}");
使用函数来调用lambda表达式(泛型委托的类型参数推断)
DoSomeCalc((a, b)=> { return a + b; }, 100, 200);
static void DoSomeCalc(Funcfunc, T x, T y)
{
T res = func(x, y);
Console.WriteLine(res);
}