技术开发 频道

.NET中的委托:细节详解

       5.自定义事件委托

  多播委托

  前面使用的每个委托都只包含一个方法调用。调用一个委托就调用一个方法调用。如果要通过一个委托调用多个方法,那就需要使用委托的多播特性。如果调用多播委托,就可以按委托添加次序连续调用多个方法。为此,委托的签名就必须返回void;否则,就只能得到委托调用的最后一个方法的结果,接下来看看多播实现。

 

namespace Multi_Delegate
{
    delegate void StringProcessor();
    
public class Person
    {
        
private string _Name;
        
public Person(string name)
        {
            this._Name
= name;
        }

        
public void Say()
        {
            Console.WriteLine(
"Hello my name is {0}, what's your name.\n", this._Name);
        }

        
public void Reply()
        {
            Console.WriteLine(
"Hello my name is {0} and nice to meet you.\n", this._Name);
        }
    }

    class Program
    {
        static void Main(
string[] args)
        {
            Person Jack
= new Person("Jack");
            Person Oliver
= new Person("Oliver");
            StringProcessor sp
= null;
//绑定多播方法调用
            sp
+= Jack.Say;
            sp
+= Oliver.Reply;
            sp();
            Console.ReadKey();
        }
    }
}

    也许有人觉得很简单,实现的确简单明了,就是通过“+”把方法调用绑定到委托变量中,如果我们用“-”就可以移除绑定到委托变量方法了。

  事件

  前面一直没有解释什么是事件,现在让我用一句话解释事件和委托的关系吧!

  事件和委托关系就像是属性和字段的关系,为了刚好的实现OOP的编程原则,事件对委托进行了封装。

  现在我们修改前面的代码,使用事件对委托进行封装。

 /// 使用事件对委托进行封装
    
/// </summary>
    
public class Say
    {
        
/// <summary>
        
/// 封装委托字段
        
/// </summary>
        
public static event SpeakDelegate speakDelegate;
        
        
/// <summary>
        
/// 调用委托具体实现方法
        
/// </summary>
        
/// <param name="name"></param>
        
public static void SayManager(string name)
        {
            speakDelegate(name);
        }
    }


        
/// <summary>
        
/// 客户端调用委托
        
/// </summary>
        
/// <param name="args"></param>
        static void Main(
string[] args)
        {
            Say.speakDelegate
+= Program.ChineseSpeaker;
            Say.speakDelegate
+= Program.EnglishSpeaker;
            Say.SayManager(
"Jackson");
            Console.ReadKey();

 

   

                                                             图5自定义委托

  现在让我们看看编译后Say类就可以充分证明我们的结论:事件是对委托封装。

                                         图6自定义事件编译后的代码

  大家看到在编译后的代码中出现了一个私有的委托变量,然后接下是一个公用事件委托变量,这进一步说明了事件是对委托的封装。

                                               图7自定义事件编译后MSIL代码

0
相关文章