一切皆地址
直接调用与间接调用
Java 中没有与委托相对应的功能实体
class Program
{
static void Main(string[] args)
{
Calculator calculator = new Calculator();
Action action = new Action(calculator.Report);
calculator.Report();//直接调用
action.Invoke();
action();//简便方法
Func func1 = new Func(calculator.Add);//泛型委托
Func func2 = new Func(calculator.Sub);
int x = 100;
int y = 200;
int z = 0;
z = func1.Invoke(x, y);//func1(x, y);
Console.WriteLine(z);
z = func2.Invoke(x, y);//func2(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;
}
}
Type t = typeof(Action);
Console.WriteLine(t.IsClass);
delegate double Calc(double x, double y);
double Add(double x, double y) { return x + y; }
double Sub(double x, double y) { return x - y; }
double Mul(double x, double y) { return x * y; }
double Div(double x, double y) { return x / y; }
- 返回值的数据类型一致
- 参数列表在个数和数据类型上一致(参数名不需要一样)
class Program
{
static void Main(string[] args)
{
ProductFactory productFactory = new ProductFactory();
WrapFactory wrapFactory = new WrapFactory();
Func func1 = new Func(productFactory.MakePizza);
Func func2 = new Func(productFactory.MakeToyCar);
Logger logger = new Logger();
Action log = new Action(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}' create 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 getProduct,Action 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 = "Ty 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 = 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();
//单播委托
//action1.Invoke();
//action2.Invoke();
//action3.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);
}
}
}
2、隐式异步调用
3、应该适时地使用接口(interface)取代一些对委托的使用
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();
stu1.DoHomework();
stu1.DoHomework();
//----------------
//间接同步调用
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.BeginInvoke(null, null);
action2.BeginInvoke(null, null);
action3.BeginInvoke(null, null);
//---------------
//显示异步调用
//第一种方式
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 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 < 5; i++)
{
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine("Main Thread {0}.", i);
Thread.Sleep(1000);
}
Console.ReadKey();
}
}
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);
}
}
}