.Net中代理和事件的区别

今天看书分别看了一下这两章,以下仅是自己总结的区别,不全面。

1.事件是特殊的代理,特殊之处在于参数。事件的参数是object 和一个继承自EventArgs的参数。如果参数不符仍然使用event关键字标识,编译器会给出warning。

2.事件使用event关键字标示,编译器将public event EventHandler<EventArgs> NewMail=null;这行代码编译为以下三个结构:

1.private EventHandler<EventArgs> NewMail=null;

2.[MethodImpl(MethodImploptions.Synchronized]

public void add_NewMail(EventHandler<EventArgs> value)

{

    NewMail=(EventHandler<EventArgs>(Delegate.Combine(NewMail,Value);

}

3.[MethodImpl(MethodImploptions.Synchronized]

public void remove_NewMail(EventHandler<EventArgs> value)

{

    NewMail=(EventHandler<EventArgs>(Delegate.Remove(NewMail,Value);

}

比委托多了两个方法,并且由于这两个方法标示了[MethodImpl(MethodImploptions.Synchronized]属性,就保证了对事件+=,-=时是线程安全的,同一时间只能一个方法执行。当事件为实例成员时,.Net对该实例对象加锁,当事件为静态成员时,对类型对象枷锁,但是这与线程同步指导方针相违背,可能会造成死锁的问题,当实例同时拥有多个事件时,并且+=,-=同时发生时会降低程序的效率。为了解决这个问题,.net提供了显示的add和remove方法,参见以下。不管怎样,代理无法保证线程安全,而事件可以。

3.事件拥有add和remove两个访问器方法并且必须同时拥有,而没有get和set方法。

为了解决上面所说的问题,程序员可以在add和remove方法lock自定义的对象,以使程序更健壮。

4.加了event关键字后该event只允许所属类调用,而普通的代理也可以在外部调用,下列代码:

namespace ConsoleApplication4
{
    public class MyEventArgs:EventArgs
    {
        private int a;
        private int b;
        public int A
        {
            get { return a; }
        }
        public int B
        {
            get { return b; }
        }
        public MyEventArgs(int a,int b)
        {
            this.a = a;
            this.b = b;
        }
    }
    public delegate void messagedelegate(object sender, MyEventArgs e);
    
    class Program
    {
        static void Main(string[] args)
        {
            Closure c = new Closure();
            c.message += c_message;
            c.fun();
            c.message(c,new MyEventArgs(3,2)); //编译正确,可以直接调用代理函数
        }

        static void c_message(object sender,MyEventArgs e)
        {
            Console.Write("c_message)"+e.A+e.B);
        }
    }
    
    public class Closure
    {
        public messagedelegate message; //没有使用event关键字标示
        public void fun()
        {
            if (message != null)
            {
                MyEventArgs e = new MyEventArgs(9, 2);
                message(this,e);
            }
        }
    }
}

当public messagedelegate message使用event标示时重新编译,提示错误“Error    1    The event 'ConsoleApplication4.Closure.message' can only appear on the left hand side of += or -= (except when used from within the type 'ConsoleApplication4.Closure') ”,事件只允许在类内部调用。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值