C#--委托


1。 什么是委托?

    委托和事件这两个概念是完全配合的。委托仅仅是函数指针,那就是说,它能够引用函数,通过传递地址的机制完成。
    委托是一个类,当你对它实例化时,要提供一个引用函数,将其作为它构造函数的参数。

  每一个委托都有自己的签名,例如:Delegate int SomeDelegate(string s, bool b);是一个委托申明,在这里,提及的签名,
   就是说SomeDelegate 这个委托 有 string 和 bool 类型的形参,返回一个int 类型。

  上面提及的:当你对委托实例化时,要提供一个引用函数,将其作为它构造函数的参数。
   这里要注意了:被引用的这个函数必须和委托有相同的签名。

  看下面的函数:

  private int SomeFunction(string str, bool bln){...}

  你可以把这个函数传给SomeDelegate的构造函数,因为他们有相似的签名(in other words,他们都有相同的形参类型和个数,并且返回相同的数据类型)。

    SomeDelegate sd = new SomeDelegate(SomeFunction);

  sd 引用了 SomeFunction,也就是说,SomeFunction已被sd所登记注册,如果你调用 sd,SomeFunction 这个函数也会被调用,
  记住:我所说 SomeFunction的含义,后面,我们会用到它。

2.

一、委托
委托类似于函数指针,但函数指针只能引用静态方法,而委托既能引用静态方法,也能引用实例方法。

委托使用分三步:1、委托声明。2、委托实例化。3、委托调用。
例程一:
using System;

namespace 委托
{
  
delegate int NumOpe(int a,int b); //委托声明
  class Class1
  
{
    
static void Main(string[] args)
    
{
      Class1 c1 
= new Class1();
      NumOpe p1 
= new NumOpe(c1.Add); //委托实例化
      Console.WriteLine(p1(1,2)); //委托调用
      Console.ReadLine();
    }


    
private int Add(int num1,int num2)
    
{
      
return(num1+num2);
    }

  }

}
例中,委托NumOpe引用了方法Add。
委托声明了以后,就可以象类一样进行实例化,实例化时把要引用的方法(如:Add)做为参数,这样委托和方法就关联了起来,就可以用委托来引用方法了。
委托和所引用的方法必须保持一致:
1、参数个数、类型、顺序必须完全一致。
2、返回值必须一致。

二、事件

事件有很多,比如说鼠标的事件:MouserMove,MouserDown等,键盘的事件:KeyUp,KeyDown,KeyPress。

有事件,就会有对事件进行处理的方法,而事件和处理方法之间是怎么联系起来的呢?委托就是他们中间的桥梁,事件发生时,委托会知道,然后将事件传递给处理方法,处理方法进行相应处理。

比如在WinForm中最常见的是按钮的Click事件,它是这样委托的:this.button1.Click += new System.EventHandler(this.button1_Click);按按钮后就会出发button1_Click方法进行处理。EventHandler就是系统类库里已经声明的一个委托。

三、自定义事件及其处理

EventHandler以及其它自定义的事件委托都是一类特殊的委托,他们有相同的形式:

delegate void 事件委托名(object sender,EventArgs e);

object用来传递事件的发生者,比如二中的Button控件就是一个事件发生者;EventArgs用来传递事件的细节。

例程二:
 
using System;

namespace 最简单的自定义事件
{
  
/// <summary>
  
/// 事件发送类
  
/// </summary>

  class Class1
  
{
    
public delegate void UserRequest(object sender,EventArgs e); //定义委托
    public event UserRequest OnUserRequest; //定义一个委托类型的事件

    
public void run()
    
{
      
while(true)
      
{
        
if(Console.ReadLine()=="a")
        
{//事件监听
          OnUserRequest(this,new EventArgs()); //产生事件
        }

      }

    }

  }


  
/// <summary>
  
/// 事件接收类
  
/// </summary>

  class Class2
  
{
    
static void Main(string[] args)
    
{
      Class1 c1 
= new Class1();
      c1.OnUserRequest 
+= new Class1.UserRequest(c1_OnUserRequest); //委托实例化后绑定到事件
      c1.run();
    }


    
private static void c1_OnUserRequest(object sender, EventArgs e)
    
{//事件处理方法
      Console.WriteLine("\t你触发了事件!");
    }

  }

}


例程三:
using System;

namespace 带事件数据的事件
{
  
/// <summary>
  
/// 带事件数据的事件类,从EventArgs继承
  
/// </summary>

  class OnUserRequestEventArgs:EventArgs
  
{
    
private string inputText;
    
public string InputText
    
{
      
get
      
{
        
return inputText;
      }

      
set
      
{
        inputText 
= value;
      }

    }

  }


  
/// <summary>
  
/// 事件发送类
  
/// </summary>

  class Class1
  
{
    
public delegate void UserRequest(object sender,OnUserRequestEventArgs e);
    
public event UserRequest OnUserRequest;

    
public void run()
    
{
      
while(true)
      
{
        Console.WriteLine(
"请输入内容:");
        
string a=Console.ReadLine();
        
//if(a=="a")
        
//{
        OnUserRequestEventArgs e1 = new OnUserRequestEventArgs();
        e1.InputText 
= a;
        OnUserRequest(
this,e1);
        
//}
      }

    }

  }


  
/// <summary>
  
/// 事件接收类
  
/// </summary>

  class Class2
  
{
    [STAThread]
    
static void Main(string[] args)
    
{
      Class1 c1 
= new Class1();
      c1.OnUserRequest 
+= new Class1.UserRequest(c1_OnUserRequest);
      c1.run();
    }


    
private static void c1_OnUserRequest(object sender, OnUserRequestEventArgs e)
    
{
      Console.WriteLine(
"\t你输入的是:"+e.InputText);
    }

  }

}

posted on 2007-03-12 15:46  shengel  阅读(89)  评论(0)    收藏  举报