一.委托的分类
1.delegate关键字
直接通过delegate关键字定义委托类,定义示例如下:
delegate void Calculate(int x, int y, int z);
此时可将返回值类型为void、参数类型为(int, int, int)的函数委托给Calculate,示例:
Calculate calculate = new Calculate(Add);//Add为符合委托标准的函数
可简写,编译器会在编译时改写为new形式,示例:
Calculate calculate = Add;
当然,还可使用lambda表达式
Calculate calculate = (x, y, z) =>
{
Console.WriteLine("Add=" + (x+y+z));
};
执行委托
calculate(参数, 参数, 参数);
2.Action类
Action类为C#提供的无返回值委托类,可理解为无返回值的delegate类,类定义如下:
public delegate void Action();
public delegate void Action<in T>(T obj);
示例:
Action<int> action = (num) =>
{
Console.WriteLine("num=" + num);
};
Action可通过泛型指定参数类型,参数数量未作限制
3.Func类
Func类为C#提供的有返回值委托类,可理解为有返回值的delegate类,类定义如下:
public delegate TResult Func<out TResult>();
public delegate TResult Func<in T, out TResult>(T arg);
示例:
Func<int, bool> action = (num) =>
{
Console.WriteLine("num=" + num);
return true;
};
Func必须通过泛型指定返回值类型,另外,也可通过泛型指定参数类型,参数数量未作限制
二.多重委托
委托的添加与移除通过"+="与"-="实现,委托对象被多重委托时,执行委托将一次性执行所有委托
示例代码
namespace ConsoleApp_1
{
internal class Program
{
static void Main(string[] args)
{
Calculate calculate = add;
calculate(1, 1);
Console.WriteLine("=====");
calculate += sub;
calculate(1, 1);
Console.WriteLine("=====");
calculate -= add;
calculate(1, 1);
}
delegate void Calculate(int x, int y);
public static void add(int x, int y)
{
Console.WriteLine("add=" + (x + y));
}
public static void sub(int x, int y)
{
Console.WriteLine("sub=" + (x - y));
}
}
}
运行效果
委托示例
class ProductFactory
{
public Product MakePizza()
{
Product product = new();
product.Name = "Pizza";
return product;
}
public Product MakeCake()
{
Product product = new();
product.Name = "Cake";
return product;
}
public Product MakeBread()
{
Product product = new();
product.Name = "Bread";
return product;
}
}
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();
Product product = getProduct();
box.Product = product;
return box;
}
}
ProductFactory productFactory = new();
WrapFactory wrapFactory = new();
Box pizzaBox = wrapFactory.WrapProduct(() => productFactory.MakePizza());
Console.WriteLine(pizzaBox.Product.Name);
将函数(MakeXXX)作为参数传入函数(WrapProduct)