c#:委托与回调函数示例
上一篇文章已经给大家详细讲解过委托的意思,如何声明定义,如何通过委托调用函数,以及委托中的多播等……今天是刚刚学到委托新的用法——可以将方法当作参数来传递,并且不需用示例委托。所以今天来给大家再次拿出来详细讲解一下
一、委托
委托理解的追加
(1)委托是c#实现回调函数的一种机制
(2)使用委托就能讲方法当作变量来进行传递——这个是比较重要的
(3)委托是引用类型,说白了委托是一种数据类型,什么数据类型——用户自定义类型,这种类型赋值赋值需要赋一个与之对应的方法,也就是返回值类型以及参数列表相同的方法
2、回调函数
专业术语:
回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。
**注意:回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。**通俗点讲就是讲某个实现函数作为参数传入另一个函数中去,当然我们可以通过委托接口等其他一些手段实现这种方式。
自己的理解:
其实说白了回调函数就是指把一个方法当作一种参数传给另一个方法去执行,目的肯定就不用说了,就是来完成某种任务或者功能。
3、委托与回调函数的示例
注意:这里讲的是同步委托的调用
同步委托掉用?
同步委托调用:就是说你去银行存钱,把钱给柜员,他们会帮你点钞、存款,然后给您存折或卡。那么您就相当于把钱委托给了柜员,让他去执行存钱的这个函数。
(1)静态委托
public delegate void Age(string a,int b);//定义了一个委托
class Found
{
//定义一个回调函数,使之能以参数的形式进行传递
public static void Much(string a,int b)
{
Console.WriteLine("我是"+a+"今年"+b+"岁了");
}
/// <summary>
/// 有参方法
/// </summary>
/// <param name="age">委托类型</param>
public static void Many(Age age)//这里就是另一方实现回调函数的地方
{
if (age!=null)//判断是否传来了一个不为空的参数
{
Console.WriteLine("有Age类型的委托");
}
age("小明",20);//这里就实现并调用了回调函数
}
}
class Program
{
static void Main(string[] args)
{
Found.Many(Found.Much);//这里就是Age委托Many方法来实现回调函数Much
}
}
(2)实例委托
delegate void DelegateAdd1();//定义一个无参的委托,类型为DekegeteAdd1类型,
delegate void DelegateAdd2(string value);//定义一个有参的委托,类型为DekegeteAdd2类型
class DelegateApp
{
//——————————————————————————————————这里涉及到了方法的重载—————————————————————————————————————————————
/// <summary>
/// 有参方法1——回调函数
/// </summary>
/// <param name="value">传递的字符串数据</param>
public void Fild1(string value)
{
Console.WriteLine("有参方法1——————{0}", value);
}
/// <summary>
/// 无参方法1——回调函数
/// </summary>
public void Fild1()
{
Console.WriteLine("无参方法1");
}
/// <summary>
/// 有参方法2——回调函数
/// </summary>
/// <param name="value">传递的字符串数据</param>
public void Fild2(string value)
{
Console.WriteLine("有参方法2——————{0}", value);
}
/// <summary>
/// 无参方法2——回调函数
/// </summary>
public void Fild2()
{
Console.WriteLine("无参方法2");
}
/// <summary>
/// 有参方法3——回调函数
/// </summary>
/// <param name="value">传递的字符串数据</param>
public void Fild3(string value)
{
Console.WriteLine("有参方法2——————{0}", value);
}
/// <summary>
/// 无参方法3——回调函数
/// </summary>
public void Fild3()
{
Console.WriteLine("无参方法3");
}
//———————————————————————————————————————以上的方法均为定义回调函数—————————————————————————————————————
//—————————————————————————————————下面的方法是委托的任务,即实现回调函数————————————————————————————————
/// <summary>
/// 执行委托的任务——实现回调函数
/// </summary>
/// <param name="add1">DelegateAdd1委托类型的参数</param>
/// <param name="add">DelegateAdd2委托类型的参数</param>
/// <param name="value">string类型的字符串</param>
public void Print(DelegateAdd1 add2,DelegateAdd2 add,string value)
{
add2();//因为add2形参对应的传过来的实参的add1,因为add2的类型就是DelegateAdd(委托类型)是无参的,又因为add1中值就是一个方法,所以就可以以方法的形式来调用输出
//这里的add2形参对应的是一个无参的方法,因为DelegateAdd1类型(委托类型)是无参的
//而add形参对应的是一个有参的方法,因为DelegateAdd2类型(委托类型)是有参的
add(value);//而这块add形参对应的值是add_01就是有参的嘛,所以就必须给它一个参数
}
//外部类的调用
class Program
{
static void Main(string[] args)
{
//第二种的
DelegateApp d = new DelegateApp();//实例化对象DelegateApp来调用类中的方法
DelegateAdd1 add1, add2, add3;//声明三个DeleagteAdd1类型(委托类型)的变量,因为这个类型是无参的,所以只能存储无参的方法
add1 = d.Fild1;//给DelegateAdd1类型的变量add1赋值一个(无参的)方法
add2 = d.Fild2;
add3 = d.Fild3;
DelegateAdd2 add_01, add_02, add_03;//声明三个Delegate类型(委托类型)的变量,,因为这个类型是有参的,所以只能存储有参的方法
add_01 = d.Fild1;//给DelegateAdd2类型的变量add_01赋值一个(有参的)方法
add_02 = d.Fild2;
add_03 = d.Fild3;
d.Print(add1, add_01,"已执行");//委托Print方法来实现回调函数Fild1(有参和无参)重载
}
}
(3)使用数组和泛型来实现委托
delegate void DelegateAdd1();
delegate void DelegateAdd2(string value);
class DelegateApp
{
/// <summary>
/// 有参方法1
/// </summary>
/// <param name="value">传递的字符串数据</param>
public void Fild1(string value)
{
Console.WriteLine("有参方法1——————{0}", value);
}
/// <summary>
/// 无参方法1
/// </summary>
public void Fild1()
{
Console.WriteLine("无参方法1");
}
/// <summary>
/// 有参方法2
/// </summary>
/// <param name="value">传递的字符串数据</param>
public void Fild2(string value)
{
Console.WriteLine("有参方法2——————{0}", value);
}
/// <summary>
/// 无参方法2
/// </summary>
public void Fild2()
{
Console.WriteLine("无参方法2");
}
/// <summary>
/// 有参方法3
/// </summary>
/// <param name="value">传递的字符串数据</param>
public void Fild3(string value)
{
Console.WriteLine("有参方法2——————{0}", value);
}
/// <summary>
/// 无参方法3
/// </summary>
public void Fild3()
{
Console.WriteLine("无参方法3");
}
//实现回调函数的方法
public void Print(DelegateAdd1[] arry,List<DelegateAdd2> list,string value)
//使用数组和泛型来将所有的回调函数全部实现,其中数组中存储的无参回调函数,泛型中存储的是有参回调函数
{
for (int i = 0; i < arry.Length; i++)//将存储在数组中的变量全部拿出来,并以方法的形式调用
{
arry[i]();//因为通过索引取的时候,arry[0]就代表一个DelegateAdd类型(委托类型)的变量,它这个变量是无参的方法,所以就可以以方法的形式来调用
}
for (int i = 0; i < list.Count; i++)//将存储在泛型中的变量全部拿出来,并以方法的形式调用
{
list[i](value);//vale就是外界传过来的string类型的实际参数
}
}
}
//————————————————————————————————————————————外部类调用——————————————————————————————————————————————
class Program
{
static void Main(string[] args)
{
DelegateApp d = new DelegateApp();//实例化对象DelegateApp来调用类中的方法
DelegateAdd1 add1, add2, add3;//声明三个DeleagteAdd1类型(委托类型)的变量,因为这个类型是无参的,所以只能存储无参的方法
add1 = d.Fild1;//给DelegateAdd1类型的变量add1赋值一个(无参的)方法
add2 = d.Fild2;
add3 = d.Fild3;
DelegateAdd2 add_01, add_02, add_03;//声明三个Delegate类型(委托类型)的变量,,因为这个类型是有参的,所以只能存储有参的方法
add_01 = d.Fild1;//给DelegateAdd2类型的变量add_01赋值一个(有参的)方法
add_02 = d.Fild2;
add_03 = d.Fild3;
DelegateAdd1[] arry = {add1,add2,add3 };//创建一个数组来存储DelegateAdd1类型的变量
List<DelegateAdd2> list= new List<DelegateAdd2>();//实例化一个泛型来存储DelegateAdd2类型的变量
//将三个变量添加到泛型中
list.Add(add_01);
list.Add(add_02);
list.Add(add_03);
d.Print(arry, list, "已执行");//委托Print方法来实现所有的回调函数,第一个参数是数组,第二个是泛型,也就是说将全部的回调方法实现了
Console.ReadKey();
}
}
以上三种方法结合后输出的结果:
以上均为自己在学习中总结的一些小知识点,希望能对您有一些帮助。如果本篇文章还有什么不完善的地方,或者对大家造成的误导,还请各位能够指出,来纠正为的错误,谢谢大家!