C# 委托—事件访问器

此文在张子阳的 C#中的委托和事件() 的基础上修改而成,由于水平所限文中,文中错漏之处在所难免(特别是在措词方面),敬请回帖斧正,涕零感激。

   委托变量和事件都可以供多个订阅者注册,如果委托定义了返回值,那么多个订阅者的方法都会向发布者返回数值,结果就是后面一个返回的方法值会覆盖前面一个的方法返回值.

例子: 

 class Delegater1
    {
        
static void Main(string[] args)
        {
            Publishser pu 
= new Publishser();
            Subscriber1 s1 
= new Subscriber1();
            Subscriber2 s2 
= new Subscriber2();
            Subscriber3 s3 
= new Subscriber3();

            pu.Eventr 
+= s1.Outer;
            pu.Eventr 
+= s2.Outer;
            pu.Eventr 
+= s3.Outer;//到此为止,有3个订阅者注册了Eventr事件,在下面触发事件的时候这三个订阅者会被依次执行,但最终的只会有一个返回值
            pu.InvokeEventr();//触发事件
            Console.ReadLine();
        }
    }

    
//定义委托
    public delegate string Delegater();

    
//定义事件发布者
    class Publishser
    {
       
//定义事件
        public event Delegater Eventr;

        
public void InvokeEventr()//触发事件
        {
            Delegater delegater 
= Eventr;
            
if (delegater != null)
                Console.WriteLine(delegater());
//输出结果
        }
    }

    
//定义事件订阅者
    class Subscriber1
    {
       
public string Outer()
       {
           Console.WriteLine(
"this is Subscriber1");
           
return "Subscriber1 Outer";
       }
    }

    
class Subscriber2
    {
        
public string Outer()
        {
            Console.WriteLine(
"this is Subscriber2");
            
return "Subscriber2 Outer";
        }
    }

    
class Subscriber3
    {
        
public string Outer()
        {
            Console.WriteLine(
"this is Subscriber3");
            
return "Subscriber3 Outer";
        }
    }

输出结果:

this is Subscriber1

this is Subscriber2

this is Subscriber3

Subscriber3 Outer

     上面输出 this is Subscriber1, this is Subscriber2, this is Subscriber3 表示三个订阅者中的outer方法都执行了,而 输出的Subscriber3 Outer则代表Subscriber3的outer方法返回值覆盖了Subscriber1, Subscriber2的outer方法返回值,

    为了避免上面的"值覆盖, 我们可能想限制只允许一个客户端注册。

方法如下:将事件声明为private的,然后提供两个方法来进行注册和取消注册  

 class Delegater2
    {
        
static void Main(string[] args)
        {
            Publishser pu 
= new Publishser();
            Subscriber1 s1 
= new Subscriber1();
            Subscriber2 s2 
= new Subscriber2();
            Subscriber3 s3 
= new Subscriber3();

            pu.DelEventr(s1.Outer);
//这里不会出错
            pu.ResEventr(s2.Outer);//注册成功
            pu.ResEventr(s3.Outer);//重新进行注册
            
            pu.InvokeEventr();
//触发事件
            Console.ReadLine();
        }
    }

    
//定义委托
    public delegate string Delegater();

    
//定义事件发布者
    class Publishser
    {
       
//定义事件
        private event Delegater Eventr;

        
public void ResEventr(Delegater De)
        {

            Eventr 
= De;//注意这里没有使用+=,来实现只能注册一次
        }
        
public void DelEventr(Delegater De)
        {
            Eventr 
-= De;//这里没有对De就行为空判断,因为即使没有注册过,不会影响程序的进行,不会抛出异常,不会有任何现象。
        }

        
public void InvokeEventr()//触发事件
        {
            Delegater delegater 
= Eventr;
            
if (delegater != null)
                Console.WriteLine(delegater());
//输出结果
        }
    }

    
//定义事件订阅者
    class Subscriber1
    {
       
public string Outer()
       {
           Console.WriteLine(
"this is Subscriber1");
           
return "Subscriber1 Outer";
       }
    }

    
class Subscriber2
    {
        
public string Outer()
        {
            Console.WriteLine(
"this is Subscriber2");
            
return "Subscriber2 Outer";
        }
    }

    
class Subscriber3
    {
        
public string Outer()
        {
            Console.WriteLine(
"this is Subscriber3");
            
return "Subscriber3 Outer";
        }
    }

输出结果为:

this is Subscriber3

Subscriber3

     此时应该注意到我们的实现方法已经类似于C#中的属性(在c#中在C#中通常一个属性对应一个类型成员,而在类型的外部对成员的操作全部通过属性来完成),我们变相的实现了。

恰恰C#提供了一种叫事件访问器(Event Accessor)用来封装委托变量。

实现方法: 


    
class Delegater3
    {
        
static void Main(string[] args)
        {
            Publishser pu 
= new Publishser();
            Subscriber1 s1 
= new Subscriber1();
            Subscriber2 s2 
= new Subscriber2();
            Subscriber3 s3 
= new Subscriber3();

            pu.Eventr 
+= s1.Outer;//注册s1
            pu.Eventr -= s1.Outer;//移除s1
            pu.Eventr += s2.Outer;//注册s2
            pu.Eventr += s3.Outer;//注册s3,覆盖s2

            pu.InvokeEventr();
//触发事件
            Console.ReadLine();
        }
    }

    
//定义委托
    public delegate string Delegater();

    
//定义事件发布者
    class Publishser
    {
        
//定义委托变量
        private Delegater eventr;
        
//定义事件
        public event Delegater Eventr
        {
            add { eventr 
= value; }
            remove { eventr 
-= value; }

        }

        
public void InvokeEventr()//触发事件
        {
            Delegater delegater 
= eventr;
            
if (delegater != null)
                Console.WriteLine(delegater());
//输出结果                                                                                        
        }
    }

    
//定义事件订阅者
    class Subscriber1
    {
        
public string Outer()
        {
            Console.WriteLine(
"this is Subscriber1");
            
return "Subscriber1 Outer";
        }
    }

    
class Subscriber2
    {
        
public string Outer()
        {
            Console.WriteLine(
"this is Subscriber2");
            
return "Subscriber2 Outer";
        }
    }

    
class Subscriber3
    {
        
public string Outer()
        {
            Console.WriteLine(
"this is Subscriber3");
            
return "Subscriber3 Outer";
        }
    }

 

 输出结果为:

this is Subscriber3

Subscriber3

注意:使用事件访问器后 只能通过委托变量来实现委托,因为不能通过事件访问器实现,事件访问器仅实现注册与反注册。 

posted @ 2009-11-11 11:03  心在天  阅读(499)  评论(0编辑  收藏  举报