在C#语言中,委托无处不在,在C#框架(包括.NET)中,委托无处不在
1 委托
1.1 什么是委托
public delegate void noreturnnoparp();
public delegate void noreturnnoparpSum(int sum);
private void btnCreateDelegate_Click(object sender, EventArgs e)
{
//noreturnnoparp noreturnnoparp = new noreturnnoparp(SayHello);
noreturnnoparp noreturnnoparp = SayHello;
//noreturnnoparp.Invoke();
noreturnnoparp();
noreturnnoparpSum noreturnnoparpSum = SayHello;
noreturnnoparpSum.Invoke(3);
}
public void SayHello()
{
Console.WriteLine("Hello World");
}
public void SayHello(int Sum)
{
for (int i = 0; i < Sum; i++)
{
Console.WriteLine($"第{i}次,Hello World");
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IPjDlhSz-1613956810883)(1.1声明委托.jpg)]
我们使用反编译工具查看一下代码
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JQQZhlbZ-1613956810885)(1.1反编译查看IL语言.jpg)]
.class 类
.ctor 构造函数
.method 方法
我们可以得到以下结论:
- 委托在IL中就是一个类
- 继承自System.MulticastDelegate(特殊类,该类无法继承)
- 能够做到把方法当作参数在另一个方法中传递或调用
- 从上面可以看出,调用的方法和委托的返回类型,参数类型都必须一致。
- 在Invoke时调用方法的运行且在Invoke时传入所需要参数
- BeginInvoke和EndInvoke是启用一个多线程使用,如果有需要可以借鉴博主《万字长文主讲介绍CSharp多线程、多进程并行开发》https://qlygmwcx.blog.csdn.net/article/details/112499286
1.2 为什么会存在委托,为什么要用委托
委托的类的实例可以放入一个方法,实例在Invoke时,就调用方法,说起来是在执行方法,为啥要做成三个步骤,基于此我们来做一个小案例分析一下。
现在有一个人,每一次见到别人都需要打招呼,见到中国人要说:{早上好},见到美国人要说:{Good Morning}。
1.2.1 基础代码
private void btnBaseCode_Click(object sender, EventArgs e)
{
Person pPerson = new Person("蔡名洋");
pPerson.CallGreeting("xiaocai");
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DelegateDemo
{
public class Person
{
public Person(string strPersonName)
{
PersonName = strPersonName;
}
public string PersonName
{
get;
private set;
}
public void CallGreeting(string strCallPersonName)
{
Console.WriteLine("招手示意..................");
Console.WriteLine($"早上好:{strCallPersonName}");
Console.WriteLine("挥手告别..................");
}
}
}
1.2.2 通过不同的函数实现对不同人群的打招呼
public class Person
{
public Person(string strPersonName)
{
PersonName = strPersonName;
}
public string PersonName
{
get;
private set;
}
public void CallGreeting4Chinese(string strCallPersonName)
{
Console.WriteLine("招手示意..................");
Console.WriteLine($"早上好:{strCallPersonName}");
Console.WriteLine("挥手告别..................");
}
public void CallGreeting4American(string strCallPersonName)
{
Console.WriteLine("招手示意..................");
Console.WriteLine($"Good Morning :{strCallPersonName}");
Console.WriteLine("挥手告别..................");
}
}
1.2.3 通过不同枚举实现对不同人群的打招呼
private void btnBaseCodeOverload_Click(object sender, EventArgs e)
{
Person pPerson = new Person("蔡名洋");
pPerson.CallGreeting("小菜", PersonType.ChinesePerson);
pPerson.CallGreeting("xiaocai", PersonType.ChinesePerson);
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DelegateDemo
{
public class Person
{
public Person(string strPersonName)
{
PersonName = strPersonName;
}
public string PersonName
{
get;
private set;
}
public void CallGreeting(string strCallPersonName,PersonType personType)
{
Console.WriteLine("招手示意..................");
switch (personType)
{
case PersonType.ChinesePerson:
Console.WriteLine($"早上好:{strCallPersonName}");
break;
case PersonType.AmericanPerson:
Console.WriteLine($"Good Morning :{strCallPersonName}");
break;
}
Console.WriteLine("挥手告别..................");
}
}
public enum PersonType
{
/// <summary>
/// 中国人
/// </summary>
ChinesePerson=0,
/// <summary>
/// 美洲人
/// </summary>
AmericanPerson=1,
}
}
点评1.2.2和1.2.3部分的代码,以及思考
1.2.4 封装打招呼类
1.2.4.1 无工厂类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DelegateDemo
{
public interface ICallGreeting
{
void CallGreeting(string strCallPersonName);
}
}
public class AmericanCallGreeting : ICallGreeting
{
public void CallGreeting(string strCallPersonName)
{
Console.WriteLine($"早上好:{strCallPersonName}");
}
}
public class ChineseCallGreeting : ICallGreeting
{
public void CallGreeting(string strCallPersonName)
{
Console.WriteLine($"早上好:{strCallPersonName}");
}
}
//界面UI代码
private void btnBaseCodeInterface_Click(object sender, EventArgs e)
{
Person pPerson = new Person("蔡名洋");
ICallGreeting pChineseCallGreeting = new ChineseCallGreeting();
pPerson.CallGreeting4Interface("小菜", pChineseCallGreeting);
ICallGreeting pAmericanCallGreeting = new AmericanCallGreeting();
pPerson.CallGreeting4Interface("xiaocai", pAmericanCallGreeting);
}
1.2.4.2 工厂类加装
//界面UI代码
private void btnBaseCodeInterface_Click(object sender, EventArgs e)
{
Person pPerson = new Person("蔡名洋");
//ICallGreeting pChineseCallGreeting = new ChineseCallGreeting();
//pPerson.CallGreeting4Interface("小菜", pChineseCallGreeting);
//ICallGreeting pAmericanCallGreeting = new AmericanCallGreeting();
//pPerson.CallGreeting4Interface("xiaocai", pAmericanCallGreeting);
ICallGreeting pChineseCallGreeting =CallGreetingFactory.GetCallGreeting(PersonType.ChinesePerson);
pPerson.CallGreeting4Interface("小菜", pChineseCallGreeting);
ICallGreeting pAmericanCallGreeting = CallGreetingFactory.GetCallGreeting(PersonType.AmericanPerson);
pPerson.CallGreeting4Interface("xiaocai", pAmericanCallGreeting);
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DelegateDemo
{
public static class CallGreetingFactory
{
public static ICallGreeting GetCallGreeting(PersonType pPersonType)
{
switch (pPersonType)
{
case PersonType.ChinesePerson:
return new ChineseCallGreeting();
case PersonType.AmericanPerson:
return new AmericanCallGreeting();
}
return null;
}
}
}
1.2.5 由上述铺垫引出Delegate类和delegate关键字
- 下面是delegate和Delegate的官方文档链接地址
delegate:https://msdn.microsoft.com/zh-cn/library/ms173171.aspx
Delegate:https://msdn.microsoft.com/zh-cn/library/system.delegate(v=vs.110).aspx
- 简单的来说就是:Delegate是个类,基类,抽象类。delegate是一个关键字
更深入一点则可以这样理解:
-
Delegate 类是委托类型的基类。 然而,只有系统和编译器可以显式地从 Delegate 类或 MulticastDelegate 类派生。 此外,还不允许从委托类型派生新类型。 Delegate 类不是委托类型,该类用于派生委托类型。
-
大多数语言实现 delegate 关键字,这些语言的编译器能够从 MulticastDelegate 类进行派生;所以,用户应当使用语言所提供的 delegate 关键字。
private void btnBaseCodeDeleggate_Click(object sender, EventArgs e)
{
Person pPerson = new Person("蔡名洋");
CallGreetingDelegate pChineseCallGreetingDelegate=DelegateCallGreetingFactory.GetCallGreetingDelegate(PersonType.ChinesePerson);
pPerson.CallGreeting4Delegate("小菜", pChineseCallGreetingDelegate);
CallGreetingDelegate AmericanCallGreetingDelegate = DelegateCallGreetingFactory.GetCallGreetingDelegate(PersonType.AmericanPerson);
pPerson.CallGreeting4Delegate("xiaocai", AmericanCallGreetingDelegate);
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DelegateDemo
{
public delegate void CallGreetingDelegate(string strCallPersonName);
public static class DelegateCallGreetingFactory
{
public static CallGreetingDelegate GetCallGreetingDelegate(PersonType pPersonType)
{
CallGreetingDelegate pReturnCallGreetingDelegate = null;
switch (pPersonType)
{
case PersonType.ChinesePerson:
pReturnCallGreetingDelegate = CallGreeting4Chinese;
break;
case PersonType.AmericanPerson:
pReturnCallGreetingDelegate = CallGreeting4American;
break;
}
return pReturnCallGreetingDelegate;
}
public static void CallGreeting4Chinese(string strCallPersonName)
{
Console.WriteLine($"早上好:{strCallPersonName}");
}
public static void CallGreeting4American(string strCallPersonName)
{
Console.WriteLine($"Good Morning :{strCallPersonName}");
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。