本人第一次写技术性BLOG,特意跑到里屋来,恳请各位批评指正!

  最近学习了C#,感觉委托与事件对于第一次接触的人来说有点特别,所以仅发此文做笔记。

  委托可以看做一种类,因为本身委托并不是类,相当于C++里面的函数指针,我的理解是,可以看做是一种对“函数方法名"的一种引用与替换。它只是表明了在创建的时候它是一种比较奇怪的名字,MS总是以EventHandler作为其方法名的结尾,然后在运行的过程中,再”编译“出相应的类。(这里我没有看过C#编译器生成的代码,所以姑且称为编译吧)

  我本身是自学过一些PHP,可以看出PHP里面本身并不存在委托这种形式,因为只要是变量名后尾接上()就可以把字符串,当做方法来运行,这算是弱类型带来的一点好处吧。

  看看来自MSDN的代码

public delegate int PerformCalculation(int x, int y);

  可以看出来它并不是类,但是委托又可以实例化

new PerformCalculation(x,y);

  所以说,委托可以看做一种函数方法名的抽象。把一些具有相同参数类型个数的方法,联系到了一起,只要是符合以上两点,那么就可以通过委托的方式来调用不同的方法。

  委托既可以在类外,也可以在类的内部来声明,代码如下:

using System;
using System.Collections.Generic;
using System.Text;

namespace Delegate
{
    //类外的委托
    public delegate void PasswordUpdatedEventHandler(string x,string y);

    class User
    {
        private string userName;
        private string userPassword;

        public User(string name, string password)
        {
            this.userName = name;
            this.userPassword = password;
        }

        public void UpdatePassword(string oldPassword, string newPassword)
        {
            if (oldPassword == this.userPassword)
            {
                this.userPassword = newPassword;
                Console.WriteLine("修改密码成功");
            }
        }

        //当然一般是不允许修改用户名的,这里只是为了说明问题
        public void UpdateName(string oldName, string newName)
        {
            if (oldName == this.userName)
            {
                this.userName = newName;
                Console.WriteLine("修改用户名成功");
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            User user = new User("green", "123");
 
           //实例化委托
       //因为委托在User的外面,且UpdatePassword不是静态方法,
       //所以需要通过user.UpdatePassword才可以调用到UpdatePassword方法
       //当然如果委托放在了User类的内部,可以相当于内部类   
           PasswordUpdatedEventHandler pwd = new PasswordUpdatedEventHandler(user.UpdatePassword);
            pwd("123", "111");
        }
    }
}

  可以看到提示说修改密码成功。新密码变为了”111“,pwd这个委托实例化出来的东东,就可以看做作为user.UpdatePassword的一种名称上的替换,当然这里只是为了方便理解才这么说的。

  委托可以组成一种链状的东东,可以把几个可以通过委托来调用的方法连起来,这样只一起,就可以执行一连串的动作了。例如上文中的class Tester类中要变成这样

class Program
{
static void Main(string[] args)
{
User user
= new User("green", "123");
//实例化委托
PasswordUpdatedEventHandler pwd;
pwd
= user.UpdateName;
pwd +
= user.UpdatePassword;

pwd(
"123", "999");
}
}

  可能例子没有什么实际的意义,这里只是为了说明。。。

  运行后结果会提示密码修改成功,注意看这里

PasswordUpdatedEventHandler pwd;
pwd
= user.UpdateName;
pwd
+= user.UpdatePassword;

  声明了一个PasswordUpdateEventHandler类型的pwd,然后赋予了user.UpdateName之后又+=了一个user.UpdatePassword。我把委托看做是一种链式的方式存储的,第二行的pwd=user.UpdateName算是声明了头结点,然后连接了下一个结点。这样只需赋值一遍pwd(”123“,”999“),就连着执行了两个函数UpdateName和UpdatePassword。

  讲委托,是为了给事件做铺垫,一般都是放在一起,用了事件,就会去执行委托来的方法。直接看代码:

using System;
using System.Collections.Generic;
using System.Text;

namespace DelegateHandlerEvent
{
//委托
public delegate void ChangedPasswordEventHandler(object sender,EventArgs e);

//用户类
class User
{
private string name;
private string password;

//事件
public event ChangedPasswordEventHandler ChangedPassword;

//构造函数,输入用户名,密码
public User(string name, string password)
{
this.name = name;
this.password = password;
}

//修改密码
public void ChangePassword(string oldPassword, string newPassword)
{
if (oldPassword == this.password)
{
this.password = newPassword;
if (ChangedPassword != null)
{
ChangedPassword(
this,null);
}
}
else
{
throw new WrongPwdException("原密码错误!");
}
}
}

//自定义异常
class WrongPwdException : Exception
{
public WrongPwdException(string msg) : base(msg)
{

}
}

class Program
{
public static void Main()
{
User user
= new User("green", "123");
//注册事件
user.ChangedPassword += new ChangedPasswordEventHandler(user_ChangedPassword);

try
{
user.ChangePassword(
"123", "456");
}
catch(WrongPwdException wpe)
{
Console.WriteLine(
"不允许修改密码:"+wpe.Message);
}
}

static void user_ChangedPassword(object sender, EventArgs e)
{
Console.WriteLine(
"成功修改密码!");
}
}
}

  大概的意思都在代码注释里,可以看看。

  代码写的很垃圾,没模仿出.net Framework的感觉来,凑合看看吧。

  事件就是扩充其他类的代码,在其他类执行到某部分的时候,其他类会看有没有事件注册。如果没有则不执行,如果有事件注册了,那么就跳转到相应的部分去执行,这样,原本的类就可以再添加新的处理方法,来扩充原有类,执行更多的功能了。

  额第一次写BLOG好累,先到这里吧,


  

posted on 2011-08-10 22:09  green.4984  阅读(946)  评论(0编辑  收藏  举报