C# Event在.Net规则下由接口定义的实现
最近在学C#(教材《C# in a nutshell》很不错的说),看完delegate(委托)以后,紧接着就是event(事件)了,个人对跟.Net相关的东西并没有什么兴趣(毕竟是会增加代码复杂度的玩意),可是后面没准用得到,而且讲完.Net那套定义规则之后紧接着就是“接口内定义事件如何实现”,遂想试试写例子看看。
.Net框架下,对于事件对应的委托有三条规则:
1.返回值必须为void——就是没有返回值;
2.参数必须有一个为object——用于转移额外信息(convey extra information),这里也可以用System.EventHandler,但其实EventHandler的说明是“没有额外信息时使用”;
3.名称必须以EventHandler结尾,个人很讨厌Handle这个词,难以解释这是个什么东西,别问,问就句柄,可是句柄又是个什么鬼?(windowsAPI PTSD)
因为没有什么C#的代码经验,所以,并不清楚接口内定义事件的具体应用场合。在不符合以上规则的情况下,
using System; namespace ForPractise
{
public delegate void MathematicFunc<T>(T e); public interface IFoo { event MathematicFunc<int> InterfaceEvent; } // if .Net use subclass of EventArgs instead of int public class Foo : IFoo
{
private int counter;
private MathematicFunc<int> _field; // private field of delegate
public event MathematicFunc<int> InterfaceEvent // explictly declare add & remove of interface IFoo
{
// ... there could have multiple fields
add { _field += value; }
remove { _field -= value; }
} private void OnBraodcast(int counts) // fire events
{
_field?.Invoke(counts);
} public int Counter
{
get { return counter; }
set
{
if (counter == value)
{
return;
}
counter = value;
OnBraodcast(counter);
}
}
} class Program
{
static int Main()
{
Foo foo = new Foo();
foo.Counter = ;
foo.InterfaceEvent += Multiple;
foo.InterfaceEvent += Ratio;
foo.Counter = ;
foo.InterfaceEvent -= Ratio;
foo.Counter = ;
foo.InterfaceEvent -= Ratio;
foo.InterfaceEvent += Ratio;
foo.Counter = ; Console.Read(); return ;
} static void Multiple(int num)
{
Console.WriteLine("{0} multiply itself {1}", num, num * num);
} static void Ratio(int num)
{
Console.WriteLine("{0} divide 0.1 {1}", num, num / 0.1d);
}
}
}
以上代码中,显示定义event.add跟event.remove可以省略——非必要的(即便显式定义了,在外部也只能通过"+="跟"-="进行订阅),直接写为"public event MathematicFunc<int> interfaceEvent; // 可以加上=null"即可。
下面则是应用.Net规则的代码,会比较肿,套用这种结构,需要额外定义System.EventArgs的子类作为参数,委托在套用泛型的时候也要多加很多东西——不过多参数就可以直接塞到EventArgs的子类里面了,也不清楚是方便了还是糟心了。同上event的显式定义也是非必要的。
using System; namespace ForPractise
{
public class FooEventArgs : EventArgs
{
public int Counter { set; get; } public FooEventArgs(int count) { Counter = count; }
} public delegate void MathematicEventHandler<TEArgs>(object source, TEArgs e) where TEArgs : EventArgs; // delegate follow the .Net framework three rules public interface IFoo { event MathematicEventHandler<FooEventArgs> InterfaceEvent; } public class Foo : IFoo
{
private int counter;
private MathematicEventHandler<FooEventArgs> _field; // private field of delegate
public event MathematicEventHandler<FooEventArgs> InterfaceEvent // explictly declare add & remove of interface IFoo
{
// ... there could have multiple fields
add { _field += value; }
remove { _field -= value; }
} private void OnBraodcast(FooEventArgs e) // fire events
{
_field?.Invoke(this, e);
} public int Counter
{
get { return counter; }
set
{
if (counter == value)
{
return;
}
counter = value;
OnBraodcast(new FooEventArgs(counter));
}
}
} class Program
{
static int Main()
{
Foo foo = new Foo();
foo.Counter = ;
foo.InterfaceEvent += Multiple;
foo.InterfaceEvent += Ratio;
foo.Counter = ;
foo.InterfaceEvent -= Ratio;
foo.Counter = ;
foo.InterfaceEvent -= Ratio;
foo.InterfaceEvent += Ratio;
foo.Counter = ; Console.Read(); return ;
} static void Multiple(object obj, FooEventArgs e) // will be quite clumsy for simple function methods.
{
Console.WriteLine("{0} multiply itself {1}", e.Counter, e.Counter * e.Counter);
} static void Ratio(object obj, FooEventArgs e)
{
Console.WriteLine("{0} divide 0.1 {1}", e.Counter, e.Counter / 0.1d);
}
}
}
其实MathematicEventHandler这个委托名不以EventHandler结尾依旧可以正常运行,应该是没有放到标准的.Net环境下,不然就是这只是约定俗成的命名法——就跟fire event部分的函数以On做前缀一样。
上面的两段运行结果都是一样的,暂时没找出来差别。还是写简单一些的好呐。
运行结果:
23 multiply itself 529
23 divide 0.1 230
12 multiply itself 144
1 multiply itself 1
1 divide 0.1 10
C# Event在.Net规则下由接口定义的实现的更多相关文章
- 注意Vietnamese_CI_AS排序规则下的特殊字符大小敏感问题
注意Vietnamese_CI_AS排序规则下的特殊字符大小敏感问题 最近,在SQL Server中遇到了Vietnamese_CI_AS排序规则的特殊字符的大小写敏感问题,是的,你没有看错,这句 ...
- jmeter将上一个接口返回值作为下一个接口的请求参数
在jmeter中有时候会用到,将上一个接口的返回值作为下一个接口的请求参数 具体操作如下: 1.首先新建一个http请求(右键线程组--添加Sampler--http请求),同时添加好接口相应的请求参 ...
- jmeter将JDBC Request查询出的数据作为下一个接口的参数
现在有一个需求,从数据库tieba_info表查出rank小于某个值的username和count(*),然后把所有查出来的username和count(*)作为参数值,用于下一个接口. tieba_ ...
- was集群下基于接口分布式架构和开发经验谈
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/luozhonghua2014/article/details/34084935 某b项目是我首 ...
- 【重点】Jmeter----- 将 JDBC Request 查询结果作为下一个接口参数方法(二)
一.说明 jmeter与数据库mysql已连接成功 二.需求 1.前置条件: 1.已user数据库的前8位手机号码作为行动计划的名称 2.行动计划的日期是2018-10-17 2.操作步骤: 1)获取 ...
- Jmeter将JDBC Request查询结果作为下一个接口参数方法(转载)
现在有一个需求,从数据库tieba_info表查出rank小于某个值的username和count(*),然后把所有查出来的username和count(*)作为参数值,用于下一个接口. tieba_ ...
- 学习笔记---Javascript事件Event、IE浏览器下的拖拽效果
学习笔记---Javascript事件Event.IE浏览器下的拖拽效果 1. 关于event常用属性有returnValue(是否允许事件处理继续进行, false为停止继续操作).srcE ...
- Jmeter将JDBC Request查询结果作为下一个接口参数方法
现在有一个需求,从数据库tieba_info表查出rank小于某个值的username和count(*),然后把所有查出来的username和count(*)作为参数值,用于下一个接口. tieba_ ...
- SpringBoot下支付宝接口的使用
SpringBoot下支付宝接口的使用 前期准备: 参考之前写过的 支付宝接口引入servlet版本 Jar包引入: <!-- 支付宝 --> <dependency> < ...
随机推荐
- linux安装数据时报错Could not execute auto check for display colors using command /usr/bin/xdpyinfo.
在redhat6.5上安装Oracle时,最后使用oracle用户执行runInstaller 报错如下,无法连接到安装有xmanager的windows服务器,也就无法图形化安装oracle ora ...
- Spring学习的第一天
Spring是以Ioc和Aop为内核,提供了表现层spring MVC 和持久层Spring JDBC等众多应用技术,还能整合开源世界众多著名的第三方框架和类库,成为使用最多的JavaEE企业应用开源 ...
- web安全技术--XSS和CSRF
Xss一般是脚本代码,主要是JS的,但是也有AS和VBS的. 主要分为反射型,存储型,DOM型三个大类. 一般来讲在手工测试的时候先要考虑的地方就是哪里有输入那里有输出. 然后是进行敏感字符测试,通常 ...
- SQl Server 中的decimal( m , n )的意思
create table sc( cno ), sno ), grade ,), primary key(cno,sno), foreign key(cno) references cou(cno), ...
- vuetify,vux,Mint UI 等框架的选择
vuetify: https://vuetifyjs.com/zh-Hans/getting-started/quick-start NutUI:https://github.com/jdf2e/nu ...
- windows下cocos2d-x工程结构讲解
这是我们新建好的工程,稍微解释一下我们开发windows的cocos应用所用到的几个文件夹的作用 Classes文件夹,存放游戏代码中的类的源码,当然我们放在别的地方也可以,只要配置好依赖关系就行了 ...
- (五十七)c#Winform自定义控件-传送带(工业)-HZHControls
官网 http://www.hzhcontrols.com 前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kww ...
- C#_.NetFramework_WebAPI项目_EXCEL数据导出
[推荐阅读我的最新的Core版文章,是最全的介绍:C#_.NetCore_Web项目_EXCEL数据导出] 项目需要引用NPOI的Nuget包: A-2--EXCEL数据导出--WebAPI项目--N ...
- HTML元素分类 块级元素 内联元素 块级内联元素
概述 HTML中存在许多元素,如<h1>,<p>,<a>,<block>,<image>,这些元素可分为三类,依次是块级元素,内联元素,块级 ...
- automaticallyAdjustsScrollViewInsets
参考链接: https://www.jianshu.com/p/a1987a7c11ba