c# 创建委托 消息订阅_C#委托(delegate、Action、Func、predicate)和事件

摘要:

声明和使用有这样一个应用场景,如果系统有异常,需要及时的通知管理员。那么需要在我们的日志记录里面添加通知管理员的功能,但是问题来了,该怎么通知管理员呢?至少现在无法知道。所以我们就需要在使用到事件。添加代码如下,如果不知道日志功能的可以参考【Log4Net日志记录的实现】//声明一个通知的委托publicdelegatevoidNoticeEventHander(stringmessage);//

一、前言

刚开始工作的时候,觉得委托和事件有些神秘,而当你理解他们之后,也觉得好像没有想象中的那么难。在项目中运用委托和事件,你会发现他非常棒,这篇博文算是自己对委托和事件的一次梳理和总结。

#39;display:none">本站访客数人

二、委托

C#中的委托,相当于C++中的指针函数,但委托是面向对象的,是安全的,是一个特殊的类,当然他也是引用类型,委托传递的是对方法的引用。

nvoke($"系统异常,请及时处理,异常信息:{message}");}在引用场景的代码,先定义一个通知管理员的方法(这里我们直接Console.WriteLine出来)publicstaticvo

2.1、delegate

声明委托就必须使用关键字“delegate”,委托是先声明,后实例化。至少0个参数,至多32个参数

根据需要程度再考虑开发相应的功能。3、显示站点总访问量和单页面访问量你懂的吧,上面两种标签代码都安装。实例效果参考:http://cubernet.cn/blog/swift-1http://lvze

格式如下所示:

erations(2);运行结果:三、事件事件是基于委托,为委托提供一种发布/订阅机制,声明事件需要使用event关键字。发布者(Publisher):一个事件的发行者,也称作是发送者(sender)

private delegate string GetAsString();

委托是一个类,所以他的实例化跟类的实例化一样,只是他总是接受一个将委托方法作为参数的构造函数。调用委托方法就有两种方式,如下所示:

连续点击n篇文章,记录n次访问量。本站总访问量次算法b:uv的方式,单个用户连续点击n篇文章,只记录1次访客数。本站访客数人次如果你是用的hexo,打开themes/你的主题/layout/_part

int i = 10;

var method = new GetAsString(i.ToString);

//调用方法一

Console.WriteLine($"method方法{method()}");

//调用方法二

Console.WriteLine($"method.Invoke方法{method.Invoke()}");

运行结果:

uot;busuanzi_value_site_uv">人

ool的委托定义一个方法:publicstaticboolFindPoints(inta){returna>=60;}定义Predicate委托Predicatepredi

2.2、Action

Action是无返回值的泛型委托,可以接受0个至16个传入参数

ng无返回值的委托前面我们【Log4Net日志记录的实现】中,就使用了Action。如:publicstaticvoidDebug(stringmessage,ActionRegistedProper

Action 表示无参,无返回值的委托

idNewBookInfoEventHandler(objectsender,BookInfoEventArgse);//publiceventNewBookInfoEventHandlerNewBo

Action 表示有传入参数int,string无返回值的委托

问量在themes/icarus/layout/common/article.ejs开头添加如下代码事实上,这段代码我并不确定是否能用由于icarus主题的配置比较特殊,有些配置项我也不太确定,于是都

前面我们【Log4Net 日志记录的实现】中,就使用了Action。如:

public static void Debug(string message, Action RegistedProperties)

{

RegistedProperties();

log.Debug(message);

}

调用方式为:

开启访问量统计功能(不蒜子)busuanzi:enable:true2、引入不蒜子并添加站点访问量在themes/icarus/layout/footer.ejs末尾添加如下代码

PFTLog.Debug("测试扩展字段", () => {

LogicalThreadContext.Properties["LogType"] = "扩展字段内容";

});

在运行中,直接运行Action中的内容即可。

是看到sender,就有种很熟悉的感觉!!!先不忙着急,我们先看下事件的声明和使用有这样一个应用场景,如果系统有异常,需要及时的通知管理员。那么需要在我们的日志记录里面添加通知管理员的功能,但是问题来

2.3、Func

Func是有返回值的泛型委托,可以接受0个至16个传入参数

ttp://www.gcrimson.comhttp://libk.nethttp://ztyoung.mehttp://blog.itmyhome.com2、显示单页面访问量要显示每篇文章的访问量,

Func 表示无参,返回值为int的委托

(";",result)}");运行结果2.5、多播委托前面的只包含了一个方法的调用,委托可以包含多个方法,这种委托就叫做多播委托。多播委托利用“+=”和“-+&r

Func 表示传入参数为object, string 返回值为int的委托

ntArgse也就是监视对象了。深入理解之后,是不是觉得也没有想象中的那么难了。四、总结这里我们讲了委托和事件,在.Net开发中使用委托和事件,可以减少依赖性和层的耦合,开发出具有更高的重用性的组件。

public static decimal GetTotal(Func func, int a, int b)

{

return func(a, b);

}

调用方式

kInfoEventArgse);//publiceventNewBookInfoEventHandlerNewBookInfo;publiceventEventHandler

在无法知道。所以我们就需要在使用到事件。添加代码如下,如果不知道日志功能的可以参考【Log4Net日志记录的实现】//声明一个通知的委托publicdelegatevoidNoticeEventHan

var total = GetTotal((a, b) => { return (decimal)a + b; }, 1, 2);

Console.WriteLine($"结果为{total}");

运行结果

.infohttp://sdxy0506.github.iohttp://www.gcrimson.comhttp://libk.nethttp://ztyoung.mehttp://blog.itm

加站点访问量在themes/icarus/layout/footer.ejs末尾添加如下代码

er.ejs添加上述脚本即可,当然你也可以添加到header中。二、安装标签(可选)只需要复制相应的html标签到你的网站要显示访问量的位置即可。您可以随意更改不蒜子标签为自己喜欢的显示效果,内容参考

位置。算法:pv的方式,单个用户点击1篇文章,本篇文章记录1次阅读量。本文总阅读量次代码中文字是可以修改的,只要保留id正确即可。实例效果参考:http://dbarobin.com/2015/04/

2.4、predicate

predicate 是返回bool型的泛型委托,只能接受一个传入参数

类型的名称都应该以EventHandler结束二、委托的原型定义:有一个void返回值,并接受两个输入参数:一个Object类型,一个EventArgs类型(或继承自EventArgs)三、事件的命名

predicate 表示传入参数为int 返回bool的委托

panid="busuanzi_value_site_pv">次

定义一个方法:

ge);//在委托的机制下我们建立以个通知事件publicstaticeventNoticeEventHanderOnNotice;调用方式publicstaticvoidDebug(stringme

public static bool FindPoints(int a)

{

return a >= 60;

}

定义Predicate委托

d-maintenance-engineer-tipshttp://blog.jamespan.me/2015/05/06/mvn-incremental-compilationhttp://cube

Predicate predicate = FindPoints;

调用

lt}");}publicstaticvoidSquare(doublev){doubleresult=v*v;Console.WriteLine($"传值:{v};Square结果为{result}

var points = new int[] {

10,

50,

60,

80,

100 };

var result = Array.FindAll(points, predicate);

Console.WriteLine($"结果为{string.Join(";", result)}");

运行结果

.infohttp://sdxy0506.github.iohttp://www.gcrimson.comhttp://libk.nethttp://ztyoung.mehttp://blog.itm

加站点访问量在themes/icarus/layout/footer.ejs末尾添加如下代码

er.ejs添加上述脚本即可,当然你也可以添加到header中。二、安装标签(可选)只需要复制相应的html标签到你的网站要显示访问量的位置即可。您可以随意更改不蒜子标签为自己喜欢的显示效果,内容参考

位置。算法:pv的方式,单个用户点击1篇文章,本篇文章记录1次阅读量。本文总阅读量次代码中文字是可以修改的,只要保留id正确即可。实例效果参考:http://dbarobin.com/2015/04/

2.5、多播委托

前面的只包含了一个方法的调用,委托可以包含多个方法,这种委托就叫做多播委托。多播委托利用“+=”和“-+”两种运算符进行添加和删除委托。

foEventArgse){Console.WriteLine($"用户:{Name},收到书名为:{e.BookName}");}}事件订阅和取消订阅vardealer=newBookDealer(

先定义两个方法

($"method方法{method()}");//调用方法二Console.WriteLine($"method.Invoke方法{method.Invoke()}");运行结果:2.2、Actio

public static void MultiplyByTwo(double v)

{

double result = v * 2;

Console.WriteLine($"传值:{v};MultiplyByTwo结果为{result}");

}

public static void Square(double v)

{

double result = v * v;

Console.WriteLine($"传值:{v};Square结果为{result}");

}

然后调用

publicBookInfoEventArgs(stringbookName){BookName=bookName;}publicstringBookName{get;set;}}publicclas

Action operations = MultiplyByTwo;

operations(1);

operations += Square;

operations(2);

运行结果:

uot;busuanzi_value_site_uv">人

ool的委托定义一个方法:publicstaticboolFindPoints(inta){returna>=60;}定义Predicate委托Predicatepredi

三、事件

事件是基于委托,为委托提供一种发布/订阅机制,声明事件需要使用event关键字。

种标签代码都安装。实例效果参考:http://cubernet.cn/blog/swift-1http://lvzejun.cn/2015/03/31/ubuntu-softwarehttp://ww

发布者(Publisher):一个事件的发行者,也称作是发送者(sender),其实就是个对象,这个对象会自行维护本身的状态信息,当本身状态信息变动时,便触发一个事件,并通知说有的事件订阅者;

制,声明事件需要使用event关键字。发布者(Publisher):一个事件的发行者,也称作是发送者(sender),其实就是个对象,这个对象会自行维护本身的状态信息,当本身状态信息变动时,便触发一个

订阅者(Subscriber):对事件感兴趣的对象,也称为Receiver,可以注册感兴趣的事件,在事件发行者触发一个事件后,会自动执行这段代码

n篇文章,只记录1次访客数。本站访客数人次如果你是用的hexo,打开themes/你的主题/layout/_partial/footer.ejs添加即可。实例效果参考:http://liam0205.

是不是看到sender,就有种很熟悉的感觉!!!先不忙着急,我们先看下事件的声明和使用

ta){returna>=60;}定义Predicate委托Predicatepredicate=FindPoints;调用varpoints=newint[]{10,50

有这样一个应用场景,如果系统有异常,需要及时的通知管理员。那么需要在我们的日志记录里面添加通知管理员的功能,但是问题来了,该怎么通知管理员呢?至少现在无法知道。所以我们就需要在使用到事件。

");dealer.NewBookInfo+=consumer2.NewBookHere;dealer.NewBook("book_abc");dealer.NewBookInfo-=consumer

添加代码如下,如果不知道日志功能的可以参考【Log4Net 日志记录的实现】

//声明一个通知的委托

public delegate void NoticeEventHander(string message);

//在委托的机制下我们建立以个通知事件

public static event NoticeEventHander OnNotice;

调用方式

kInfoEventArgse);//publiceventNewBookInfoEventHandlerNewBookInfo;publiceventEventHandler

在无法知道。所以我们就需要在使用到事件。添加代码如下,如果不知道日志功能的可以参考【Log4Net日志记录的实现】//声明一个通知的委托publicdelegatevoidNoticeEventHan

public static void Debug(string message, Action RegistedProperties)

{

RegistedProperties();

log.Debug(message);

//执行通知

OnNotice?.Invoke($"系统异常,请及时处理,异常信息:{message}");

}

在引用场景的代码,先定义一个通知管理员的方法(这里我们直接Console.WriteLine出来)

开头添加如下代码事实上,这段代码我并不确定是否能用由于icarus主题的配置比较特殊,有些配置项我也不太确定,于是都配置了上去网站上线时间展示效果展示看看我博客最下方的展示效果吧:how2playli

public static void Notice(string message)

{

Console.WriteLine($"通知内容为{message}");

}

先注册,然后触发异常消息

g.Debug("测试扩展字段",()=>{LogicalThreadContext.Properties["LogType"]="扩展字段内容";});运行结果这里面我只需要定义好发布者,你可

//注册方式一

PFTLog.OnNotice += Notice;

//注册方式二

//PFTLog.OnNotice += new PFTLog.NoticeEventHander(Notice);

PFTLog.Debug("测试扩展字段", () => {

LogicalThreadContext.Properties["LogType"] = "扩展字段内容";

});

运行结果

.infohttp://sdxy0506.github.iohttp://www.gcrimson.comhttp://libk.nethttp://ztyoung.mehttp://blog.itm

加站点访问量在themes/icarus/layout/footer.ejs末尾添加如下代码

er.ejs添加上述脚本即可,当然你也可以添加到header中。二、安装标签(可选)只需要复制相应的html标签到你的网站要显示访问量的位置即可。您可以随意更改不蒜子标签为自己喜欢的显示效果,内容参考

位置。算法:pv的方式,单个用户点击1篇文章,本篇文章记录1次阅读量。本文总阅读量次代码中文字是可以修改的,只要保留id正确即可。实例效果参考:http://dbarobin.com/2015/04/

这里面我只需要定义好发布者,你可以以任何方式订阅,是不是很非常简单。

//ztyoung.mehttp://blog.itmyhome.com2、显示单页面访问量要显示每篇文章的访问量,复制以下代码添加到你需要显示的位置。算法:pv的方式,单个用户点击1篇文章,本篇文章

弄明白了上面的事件,我们在来说说.Net经常出现的object sender和EventArgs e

,委托可以包含多个方法,这种委托就叫做多播委托。多播委托利用“+=”和“-+”两种运算符进行添加和删除委托。先定义两个方法publicstaticvoi

.Net Framework的编码规范:

总结这里我们讲了委托和事件,在.Net开发中使用委托和事件,可以减少依赖性和层的耦合,开发出具有更高的重用性的组件。busuanzi计数脚本busuanzi官方指引一、安装脚本(必选)要使用不蒜子必须

一、委托类型的名称都应该以EventHandler结束

是有返回值的泛型委托,可以接受0个至16个传入参数Func表示无参,返回值为int的委托Func表示传入参数为object,st

二、委托的原型定义:有一个void返回值,并接受两个输入参数:一个Object 类型,一个 EventArgs类型(或继承自EventArgs)

ewBookInfo?.Invoke(this,newBookInfoEventArgs(bookName));}}事件订阅者publicclassConsumer{publicConsumer(st

三、事件的命名为 委托去掉 EventHandler之后剩余的部分

0个参数,至多32个参数格式如下所示:privatedelegatestringGetAsString();委托是一个类,所以他的实例化跟类的实例化一样,只是他总是接受一个将委托方法作为参数的构造函数

四、继承自EventArgs的类型应该以EventArgs结尾

值,并接受两个输入参数:一个Object类型,一个EventArgs类型(或继承自EventArgs)三、事件的命名为委托去掉EventHandler之后剩余的部分四、继承自EventArgs的类型应

现在我们以一个新书发布的自定义事件为例

t;次|

创建对应的类文件:

事件者发布代码:

espan.me/2015/05/06/mvn-incremental-compilationhttp://cubernet.cn/blog/optimization-3注意:不蒜子为保持极简,暂不支

public class BookInfoEventArgs : EventArgs

{

public BookInfoEventArgs(string bookName)

{

BookName = bookName;

}

public string BookName { get; set; }

}

public class BookDealer

{

//泛型委托,定义了两个参数,一个是object sender,第二个是泛型 TEventArgs 的e

//简化了如下的定义

//public delegate void NewBookInfoEventHandler(object sender, BookInfoEventArgs e);

//public event NewBookInfoEventHandler NewBookInfo;

public event EventHandler NewBookInfo;

public void NewBook(string bookName)

{

RaiseNewBookInfo(bookName);

}

public void RaiseNewBookInfo(string bookName)

{

NewBookInfo?.Invoke(this, new BookInfoEventArgs(bookName));

}

}

事件订阅者

ations(1);operations+=Square;operations(2);运行结果:三、事件事件是基于委托,为委托提供一种发布/订阅机制,声明事件需要使用event关键字。发布者(Publ

public class Consumer

{

public Consumer(string name)

{

Name = name;

}

public string Name { get; set; }

public void NewBookHere(object sender, BookInfoEventArgs e)

{

Console.WriteLine($"用户:{Name},收到书名为:{ e.BookName}");

}

}

事件订阅和取消订阅

s的e//简化了如下的定义//publicdelegatevoidNewBookInfoEventHandler(objectsender,BookInfoEventArgse);//publicev

var dealer = new BookDealer();

var consumer1 = new Consumer("用户A");

dealer.NewBookInfo += consumer1.NewBookHere;

dealer.NewBook("book112");

var consumer2 = new Consumer("用户B");

dealer.NewBookInfo += consumer2.NewBookHere;

dealer.NewBook("book_abc");

dealer.NewBookInfo -= consumer1.NewBookHere;

dealer.NewBook("book_all");

运行结果

.infohttp://sdxy0506.github.iohttp://www.gcrimson.comhttp://libk.nethttp://ztyoung.mehttp://blog.itm

加站点访问量在themes/icarus/layout/footer.ejs末尾添加如下代码

er.ejs添加上述脚本即可,当然你也可以添加到header中。二、安装标签(可选)只需要复制相应的html标签到你的网站要显示访问量的位置即可。您可以随意更改不蒜子标签为自己喜欢的显示效果,内容参考

位置。算法:pv的方式,单个用户点击1篇文章,本篇文章记录1次阅读量。本文总阅读量次代码中文字是可以修改的,只要保留id正确即可。实例效果参考:http://dbarobin.com/2015/04/

经过这个例子,我们可以知道Object sender参数代表的是事件发布者本身,而EventArgs e 也就是监视对象了。深入理解之后,是不是觉得也没有想象中的那么难了。

tAsString();委托是一个类,所以他的实例化跟类的实例化一样,只是他总是接受一个将委托方法作为参数的构造函数。调用委托方法就有两种方式,如下所示:inti=10;varmethod=newGe

四、总结

这里我们讲了委托和事件,在.Net开发中使用委托和事件,可以减少依赖性和层的耦合,开发出具有更高的重用性的组件。

quare结果为{result}");}然后调用Actionoperations=MultiplyByTwo;operations(1);operations+=Squar

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值