C#学习笔记(补充)——扩展方法、事件
(搬运自我在SegmentFault的博客)
一、扩展方法
扩展方法使你能够向现有类型“添加”方法,而无需创建新的派生类型、重新编译或以其他方式修改原始类型。
注意事项:
- 扩展方法需要是静态方法。
- 第一个参数指明作用的类型,并且用
this
关键字修饰。 - 其他参数跟在第一个参数的后面。
- 需要使用
using
指令将扩展方法所在的命名空间导入到源代码中。 - 该类型以实例方法的形式调用该方法。
- 编译器生成的中间语言 (IL) 会将代码转换为对静态方法的调用。
- 扩展方法无法访问它们所扩展的类型中的私有变量。
注意到C#中的StringBuilder
类没有实现Java中的Reverse()
方法,可以通过扩展方法实现:
namespace ExtensionMethod
{
public static class StringBuilderExtension
{
public static StringBuilder Reverse(this StringBuilder builder)
{
StringBuilder result = new StringBuilder();
for(int i=builder.Length-1;i>=0;i--)
{
result.Append(builder[i]);
}
return result;
}
}
}
新建一个测试类进行测试:
using ExtensionMethod;
static class TestStringBuilderExtension
{
static void Main()
{
StringBuilder builder = new StringBuilder("ABC");
StringBuilder newBuilder = builder.Reverse();
Console.WriteLine(newBuilder);
Console.Read();
}
}
成功为StringBuilder
添加了翻转的方法。
事件
C#中使用委托来实现事件。使用了观察者模式,即有一个事件的发布者Publisher,和事件的订阅者Subscriber。
委托需要有两个参数,第一个参数为object
类型,表示事件的发送者,第二个参数为EventArgs
类型或继承自它。
但通常建议使用.Net Framework定义的事件模式,使用EventHandler
类。EventHandler
又分为使用泛型和不使用泛型两种情况。
使用自定义的委托类型:
public delegate void CustomEventHandler(object sender, CustomEventArgs a);
非泛型的EventHandler:
public event EventHandler RaiseCustomEvent;
泛型的EventHandler:
public event EventHandler<CustomEventArgs> RaiseCustomEvent;
处理事件的方法应该是声明的委托的类型。
void HandleCustomEvent(object sender, CustomEventArgs a){ /* do something here */ }
订阅事件使用+=
,取消订阅使用-=
:
publisher.RaiseCustomEvent += HandleCustomEvent;
以使用泛型的情况为例,假设事件发生调用OnRaiseCustomEvent
方法。
class Publisher
{
public event EventHandler<CustomEventArgs> RaiseCustomEvent;
public void DoSomething()
{
OnRaiseCustomEvent(new CustomEventArgs("Did something"));
}
protected virtual void OnRaiseCustomEvent(CustomEventArgs e)
{
if (RaiseCustomEvent != null)
{
RaiseCustomEvent(this, e);
}
}
}
订阅者在其构造函数添加订阅:
class Subscriber
{
public Subscriber(Publisher pub)
{
pub.RaiseCustomEvent += HandleCustomEvent;
}
void HandleCustomEvent(object sender, CustomEventArgs e){ /* some implementation */ }
}
参考资料
[1] http://technet.microsoft.com/zh-cn/bb383977
[2] http://msdn.microsoft.com/zh-cn/library/8627sbea.aspx
[3] http://msdn.microsoft.com/zh-cn/library/ms366768.aspx
[4] http://msdn.microsoft.com/zh-cn/library/w369ty8x.aspx
[5] http://www.tracefact.net/CSharp-Programming/Delegates-and-Events-in-CSharp.aspx
C#学习笔记(补充)——扩展方法、事件的更多相关文章
- 深度学习笔记:优化方法总结(BGD,SGD,Momentum,AdaGrad,RMSProp,Adam)
深度学习笔记:优化方法总结(BGD,SGD,Momentum,AdaGrad,RMSProp,Adam) 深度学习笔记(一):logistic分类 深度学习笔记(二):简单神经网络,后向传播算法及实现 ...
- STM32 FSMC学习笔记+补充(LCD的FSMC配置)
STM32 FSMC学习笔记+补充(LCD的FSMC配置) STM32 FSMC学习笔记 STM32 FSMC的用法--LCD
- swift学习笔记4——扩展、协议
之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...
- pygame学习笔记(3)——时间、事件、文字
转载请注明:@小五义 http://www.cnblogs.com/xiaowuyi 1.运动速率 上节中,实现了一辆汽车在马路上由下到上行驶,并使用了pygame.time.delay(200 ...
- java学习笔记5--类的方法
接着前面的学习: java学习笔记4--类与对象的基本概念(2) java学习笔记3--类与对象的基本概念(1) java学习笔记2--数据类型.数组 java学习笔记1--开发环境平台总结 本文地址 ...
- Java设计模式学习笔记(三) 工厂方法模式
前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 1. 简介 上一篇博客介绍了简单工厂模式,简单工厂模式存在一个很严重的问题: 就是当系统需要引入 ...
- Object C学习笔记10-静态方法和静态属性
在.NET中我们静态使用的关键字static有着举足轻重的作用,static 方法可以不用实例化类实例就可以直接调用,static 属性也是如此.在Object C中也存在static关键字,今天的学 ...
- Swift 学习笔记(扩展和泛型)
在开始介绍Swift中的扩展之前,我们先来回忆一下OC中的扩展. 在OC中如果我们想对一个类进行功能的扩充,我们会怎么做呢. 对于面向对象编程的话,首先会想到继承,但是继承有两个问题. 第一个问题:继 ...
- [读书笔记]C#学习笔记二: 委托和事件的用法及不同.
前言: C#委托是什么 c#中的委托可以理解为函数的一个包装, 它使得C#中的函数可以作为参数来被传递, 这在作用上相当于C++中的函数指针. C++用函数指针获取函数的入口地址, 然后通过这个指针 ...
- jQuery来源学习笔记:扩展的实用功能
// 扩展的实用功能 jQuery.extend({ // http://www.w3school.com.cn/jquery/core_noconflict.asp // 释放$的 jQuery 控 ...
随机推荐
- Android性能优化之:ViewStub
ViewStub是Android布局优化中一个很不错的标签/控件,直接继承自View.虽然Android开发人员基本上都听说过,但是真正用的可能不多. ViewStub可以理解成一个非常轻量级的Vie ...
- tomcat, jdk, eclipse, ant的安装,设置及常见问题
1.tomcat 安装: 安装版:在官方下载tomcat的安装版,根据提示一步步操作,很简单的 解压版:在官方下载tomcat的解压版,放到要安装的目录中解压版即可 同以前的找到设置环境变量的地方. ...
- 一步一步学习Unity3d学习笔记系1.1
最近开始在学习Unity3D,在网上找到了一些教程利用晚上回家休息的时间自学了一下,我就是一个小白,对Unity3D什么都不懂,可能需要一些美工的功底.刚好有点,需要点编程的基础,也好我也有点,对C# ...
- JavaScript数据结构,队列和栈
在JavaScript中为数组封装了大量的方法,比如:concat,pop,push,unshift,shift,forEach等,下面我将使用JavaScript提供的这些方法,实现队列和栈的操作. ...
- EXT学习之——Ext下拉框绑定以及级联写法
/*******步骤有四个,缺一不可*********/ function () {xxxxxx = Ext.extend(construct, {InitControl: function () { ...
- 简单JS实现对表的行的增删
这段代码非常的简单,仅仅作为自己的一个小小的记录! ok,先上一个简单的图例,效果如下(注意:这只是一个简单的例子,不过可以根据这个简单的例子,变化出更为复杂的效果)! 代码也非常的简单,如下所示(注 ...
- 图的最短路算法 Dijkstra及其优化
单源最短路径算法 时间复杂度O(N2) 优化后时间复杂度为O(MlogN)(M为图中的边数 所以对于稀疏图来说优化后更快) 不支持有负权的图 #include<iostream> usin ...
- 学习练习 java 实例属性 静态属性
package com.hanqi; public class Test11Car11 { //静态 //实例属性 private int m = 0; //静态属性 //所有实例共有的,在内存里只有 ...
- Digest [IAB_SRI_Online_Advertising_Effectiveness]
http://www.pwc.com/en_GX/gx/entertainment-media/pdf/IAB_SRI_Online_Advertising_Effectiveness_v3.pdf
- GLES & Shader Language 易错集锦
1. vertex shader 和 fragment shader 通过varying变量传递数据, 如下代码在编译fragment shader时候会提示编译错误 vertex shader F ...