亚瑟狼

网络的精神就是共享
  博客园  :: 首页  :: 新随笔  :: 联系 :: 管理

C#中的Event,多余乎?不多余。

Posted on 2008-06-11 13:51  冯满天  阅读(324)  评论(0编辑  收藏  举报

C#中的Event,多余乎?不多余。

学C#以来,感叹于Delegate带来的方便,但是也烦恼于Event带来的困惑,实在搞不懂,既然有了Delegate,为什么还要有个Event呢?如果说有了Event,为什么还要保留Delegate呢?

我们先看看C#为什么会有了Delegate还要引入Event。
先看下面一个例子

有这样一个类
public delegate void MyDelegate();
public class MyClass{
    public MyDelegate myDelegate;
}

我们有个方法
private void MyFunction(){
//....我们想要处理的事情
}

我们要把自己的方法注册进去,让MyClass在适当的时候运行我们的方法。
于是
MyClass myClass = new MyClass();
myClass.myDelegate = new Mydelegate(MyFunction);

但是有一个问题是,因为在MyClass里面myDelegate被声名为public,那么即使在类的外面也可以直接调用所有注册了的方法
myClass.myDelegate();

而实际上,我们并不像让外面的类来呼叫,这些注册给myDelegate的方法,这违反了面向对象编程的封装,于是我们就想到了把myDelegate声名成private,这样只有在MyClass内部才可以使用它。
但是这样问题又来了,由于我们把myDelegate声名成了private,所以我们没有办法直接给把方法委托给它了。
于是我们必须额外的再增加两个方法,对其进行增加,减少委托

public class MyClass{
    private MyDelegate myDelegate;
    public void Add_MyDelegate(MyDelegate d){
         myDelegate+=d;
    }
    public void Delete_MyDelegate(MyDelegate d){
         myDelegate-=d;
    }
}

这样就可以达到我们的目的了,但是这样就会多出很多的代码。
既然大家都有这样的需求,那么再规定一个关键字,使得delegate的成员变量既可以直接用+=,-=来进行添加,删除委托,有不可以在类外部使用它,岂不是更加方便?

当,当,当当

于是Event闪亮登场,只要我们在MyClass中的myDelegate成员变量前面再添加一个关键字event,代码如下

public class MyClass{
    public event MyDelegate myDelegate;
}

那么我们就可以这样来添加,删除委托方法
MyClass myClass =new MyClass();
myClass.myDelegate +=new MyDelegate(MyFunction);
myClass.myDelegate -=new MyDelegate(MyFunction);
但是我们却不可以这样使用它

myClass.myDelegate();//编译错误

另外event相对于delegate还有一个限制,那就是不能用=对其所声名的成员进行委托

myclass.myDelegate = new MyDelegate(MyFunction);//编译错误

也就是说,如果想在类外面使用event所修饰的成员变量,那么成员变量仅且只能出现在+=或者-=的左边。

现在大概应该知道为什么会存在一个叫Event的东西了。