(搬运自我在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