C#复习笔记-委托
委托是一种引用类型,委托定义了了一类可以被委托实例调用的方法。它定义了方法的返回值类型和参数类型。如:定义了一个名为Transformer的委托类型,它有一个int类型的返回值,带有一个int类型的参数。可以将任何类型或者结构中与委托类型匹配的方法传递给委托,可以是静态方法也可以是实例方法。如下:
delegate int Transformer(int x);//定义了一个委托类型Transformer,接收一个int类型的参数,有一个int类型的返回值
class Test
{
static void Main()
{
Transformer trans = Square;//将方法复制给委托变量就能创建一个委托的实例
int num = trans(4);//像调用方法一样调用委托的实例
Console.WriteLine(num);
Console.ReadKey();
}
static int Square(int x) => x * x;
委托实例是调用者的代理,调用者调用委托,委托调用目标方法。
委托(delegate)提供了一种回调函数的机制,可以将委托当做参数传递给另外一个方法。委托的回调方法是类型安全的。如下的例子中定义了一个返回值为void的委托FeedBack,委托指定的方法接收一个int类型的参数。Test类定义了一个静态方法Counter,这个方法接收from,to两个int类型的参数和一个 FeedBack类型的委托fb,他是一个FeedBack委托对象的引用。如果fb不为null,就调用由fb变量指定的回调方法。
delegate void FeedBack(int value);//定义一个委托类型,无返回值,接收一个int类型的参数
class Test
{
static void Main()
{
FeedBack fb = FeedBackCallBack;//创建委托实例
Counter(10, 20, fb);//将委托当做参数传递给另外一个方法
Console.ReadKey();
}
static void Counter(int from, int to, FeedBack fb)
{
for (int val = from; val < to; val++)
{
if (fb != null)
fb(val);
}
}
/// <summary>
/// 回调函数
/// </summary>
static void FeedBackCallBack(int value)
{
Console.WriteLine($"items={value}");
}
}
委托可以调用多个方法,称为多播委托。委托使用加法运算符或加法赋值运算符(“+”或“+=”)像委托列表添加新的方法,使用减法运算符或减法赋值运算符(- 或 -=)删除委托列表中的方法。委托会按照添加的顺序依次触发。如果一个多播委托拥有非void类型的返回值,则调用者从最后一个触发的方法接收返回值。前面的方法任然会被调用,但是返回值会被丢弃。
delegate void FeedBack(int value);//定义一个委托类型,无返回值,接收一个int类型的参数 class Test { static void Main() { FeedBack fb =FeedBackMethod;//创建委托实例 fb += FeedBackMethod2; Counter(10, fb);//将委托当做参数传递给另外一个方法 Console.ReadKey(); } static void Counter(int num, FeedBack fb) { if (fb != null) fb(num); } static void FeedBackMethod(int value) { Console.WriteLine($"items1={value}"); } static void FeedBackMethod2(int value) { Console.WriteLine($"items2={value}"); } }//输出:items1=10,items2=10
委托可以包含泛型类型的参数:
public delegate T Transformer<T>(T arg);
Func和Action委托
Action是无返回值的泛型委托,Action<int,int> 表示定义一个无返回值接收2个int类型的参数的委托。
Func是有返回值的泛型委托,Func<int>表示定义一个无参数,返回值为int类型的委托。Func<String,int>表示接收一个String类型参数,返回值为int的委托。Func<String,int,int>表示接收一个String类型参数,1个int类型参数,返回值为int的委托。
委托可以有比它的目标方法更具体的参数类型,这称为委托的逆变。如:
delegate void StringAction(string str); public class Test { static void Main() { StringAction action = ObjectAction; action("你好呀"); Console.ReadKey(); } static void ObjectAction(object obj)=>Console.WriteLine(obj);//输出:你好呀
委托的目标方法可能返回比委托声明的返回值类型更加具体的返回值类型,这称为委托的协变。 如:
delegate object ObjectAction(); public class Test { static void Main() { ObjectAction action = StringAction; object result = action(); Console.WriteLine(result);//输出:你好吗 Console.ReadKey(); } static string StringAction() => "你好吗"; }
ObjectAction委托期望返回一个object类型。但是目标方法返回了一个String类型,只要返回的是object的子类这样也是可以的,因为委托的返回值类型是协变的。