事件(二)

如何:实现接口事件

接口可声明事件。下面的示例演示如何在类中实现接口事件。接口事件的实现规则与任何接口方法或属性的实现规则基本相同。

在类中实现接口事件

在类中声明事件,然后在适当的位置调用该事件。

public   interface  IDrawingObject
{
    
event EventHandler ShapeChanged;
}

public   class  MyEventArgs : EventArgs  {…}
public   class  Shape : IDrawingObject
{
    
event EventHandler ShapeChanged;
    
void ChangeShape()
    
{
        
// Do something before the event…
        OnShapeChanged(new MyEventsArgs(…));
        
// or do something after the event. 
    }

    
protected virtual void OnShapeChanged(MyEventArgs e)
    
{
        
if(ShapeChanged != null)
        
{
           ShapeChanged(
this, e);
        }

    }

}

 

示例

下面的示例演示如何处理以下的不常见情况:您的类是从两个以上的接口继承的,每个接口都含有同名事件。在这种情况下,您至少要为其中一个事件提供显式接口实现。为事件编写显式接口实现时,必须编写addremove事件访问器。这两个事件访问器通常由编译器提供,但在这种情况下编译器不能提供。

您可以提供自己的访问器,以便指定这两个事件是由您的类中的同一事件表示,还是由不同事件表示。例如,根据接口规范,如果事件应在不同时间引发,则可以将每个事件与类中的一个单独实现关联。在下面的示例中,订户将形状引用强制转换为IShapeIDrawingObject,从而确定自己将会接受哪个OnDraw事件。

namespace  WrapTwoInterfaceEvents {
        
using System;
        
        
public interface IDrawingObject{
                
//Raise this event before drawing
                
//the object
                event EventHandler OnDraw;
            }

        
        
public interface IShape{
                
//Raise this event after drawing
                
//the shape.
                event EventHandler OnDraw;
            }

        
        
//Base class event publisher inherits two
        
//interfaces, each with an OnDraw event
        public class Shape : IDrawingObject, IShape{
                
//Create an event for each interface event
                event EventHandler PreDrawEvent;
                
event EventHandler PostDrawEvent;
                
                
//Explicit interface implementation required.
                
//Associate IDrawingObject's event with
                
//PreDrawEvent
                event EventHandler IDrawingObject.OnDraw{
                        add
{
                                PreDrawEvent 
+= value;
                            }

                        remove
{
                                PreDrawEvent 
-= value;
                            }

                    }

                
                
//Explicit interface implementation required.
                
//Associate IShape's event with
                
//PostDrawEvent
                event EventHandler IShape.OnDraw{
                        add
{
                                PostDrawEvent 
+= value;
                            }

                        remove
{
                                PostDrawEvent 
-= value;
                            }

                    }

                
                
//For the sake of simplicity this one method
                
//implements both interfaces.
                public void Draw(){
                        
//Raise IDrawingObject's event before the object is drawn.
                        EventHandler handler = PreDrawEvent;
                        
if (handler != null){
                                handler(
this,new EventArgs());
                            }

                        Console.WriteLine(
"Drawing a shape.");
                        
                        
//RaiseIShape's event after the object is drawn.
                        handler = PostDrawEvent;
                        
if (handler != null){
                                handler(
this,new EventArgs());
                            }

                    }

            }

            
        
public class Subscriber1{
                    
//References the shape object as an IDrawingObject
                    public Subscriber1(Shape shape){
                            IDrawingObject d 
= (IDrawingObject)shape;
                            d.OnDraw 
+= new EventHandler(d_OnDraw);
                        }

                    
                    
void d_OnDraw(object sender,EventArgs e){
                            Console.WriteLine(
"Sub1 receives the IDrawingObject event.");
                        }

                }

                
        
//References the shape object as an IShape
        public class Subscriber2{
                
public Subscriber2(Shape shape){
                        IShape d 
= (IShape)shape;
                        d.OnDraw 
+= new EventHandler(d_OnDraw);
                    }

                        
                
void d_OnDraw(object sender,EventArgs e){
                        Console.WriteLine(
"Sub2 receives the IShape event.");
                    }

            }

                    
        
public class Program2{
                
static void Main(string[] args){
                        Shape shape 
= new Shape();
                        Subscriber1 sub 
= new Subscriber1(shape);
                        Subscriber2 sub2 
= new Subscriber2(shape);
                        shape.Draw();
                        
                        Console.WriteLine(
"Press Enter to close this window.");
                        Console.ReadLine();
                    }

            }

    }


如何:使用字典存储事件实例

accessor-declarations的一种用法是公开大量的事件但不为每个事件分配字段,而是使用字典来存储这些事件实例。这只有在具有非常多的事件、但您预计大部分事件都不会实现时才有用。

示例

public   delegate   void  EventHandler1( int  i);
public   delegate   void  EventHandler2( string  s);

public   class  PropertyEventsSample {
        
private System.Collections.Generic.Dictionary<string,System.Delegate> eventTable;
        
        
public PropertyEventsSample(){
                eventTable 
= new System.Collections.Generic.Dictionary<string,System.Delegate>();
                eventTable.Add(
"Event1",null);
                eventTable.Add(
"Event2",null);
            }

        
        
public event EventHandler1 Event1{
                add
{
                        eventTable[
"Event1"= (EventHandler1)eventTable["Event1"+ value;
                    }

                remove
{
                        eventTable[
"Event1"= (EventHandler1)eventTable["Event1"- value;
                    }

            }

        
        
public event EventHandler2 Event2{
                add
{
                        eventTable[
"Event2"= (EventHandler2)eventTable["Event2"+ value;
                    }

                remove
{
                        eventTable[
"Event2"= (EventHandler2)eventTable["Event2"- value;
                    }

            }

        
        
internal void RaiseEvent1(int i){
                EventHandler1 handler1;
                
if (null != (handler1 = (EventHandler1)eventTable["Event1"])){
                        handler1(i);
                    }

            }

        
        
internal void RaiseEvent2(string s){
                EventHandler2 handler2;
                
if (null != (handler2 = (EventHandler2)eventTable["Event2"])){
                        handler2(s);
                    }

            }

    }



public   class  TestClass2 {
        
public static void Delegate1Method(int i){
                System.Console.WriteLine(i);
            }

        
        
public static void Delegate2Method(string s){
                System.Console.WriteLine(s);
            }

        
        
static void Main(){
                PropertyEventsSample p 
= new PropertyEventsSample();
                
                p.Event1 
+= new EventHandler1(TestClass.Delegate1Method);
                p.Event1 
+= new EventHandler1(TestClass.Delegate1Method);
                p.Event1 
-= new EventHandler1(TestClass.Delegate1Method);
                p.RaiseEvent1(
2);
                
                p.Event2 
+= new EventHandler2(TestClass.Delegate2Method);
                p.Event2 
+= new EventHandler2(TestClass.Delegate2Method);
                p.Event2 
-= new EventHandler2(TestClass.Delegate2Method);
                p.RaiseEvent2(
"TestString");
            }

    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值