委托的使用
事件是一种机制,事件是通过委托实现的,所以看明白了委托,对于事件也就能更好的理解了。先看下面一个小例子。
这是描述不同语言的程序员的代码:
比如使用c#的程序员我们这样描述,其中programername参数表示这个程序员的姓名。
public void csharpprogramer(string programername) { console.writeline(string.format("{0} 使用c#编程!", programername)); }
使用java的,
public void javaprogramer(string programername) { console.writeline(string.format("{0} 使用java语言编程!")); }
那么这么多语言,怎么区分这是哪个程序员呢?使用一个枚举来表示,
public enum programlanguage { csharp, c, java }
那么进行一个完整的描述,代码如下:
public class programerdescription { //01 public void csharpprogramer(string programername) { console.writeline(string.format("{0} 使用c#编程!", programername)); } public void cprogramer(string programername) { console.writeline(string.format("{0}使用c语言编程!", programername)); } public void javaprogramer(string programername) { console.writeline(string.format("{0} 使用java语言编程!")); } //02 public void description(string programername, programlanguage type) { switch (type) { case programlanguage.csharp: csharpprogramer(programername); break; case programlanguage.c: cprogramer(programername); break; case programlanguage.java: javaprogramer(programername); break; default: console.writeline("a kind of new language that you never heard of."); break; } } } public enum programlanguage { csharp, c, java }
调用:
programerdescription pm = new programerdescription(); pm.description("杨友山", programlanguage.csharp);
这时,输出"杨友山 使用c#编程!";
这样就初步完成了一个对程序员描述的简单实现。这里的description方法是通过一个枚举类型来区别不同的语言。这样它的维护性是比较差的,因为还有很多编程语言(c++,php,等),如果想加一种语言就要增加一个对应的方法,然后就要修改programlanguage这个枚举类型。增加方法对原程序影响不大,因为可以用分部类来实现,而修改枚举就不合适了,这也不符合面向对象设计思想的开放封闭原则。
那么在description方法中怎么处理呢,也就是不用枚举了,description方法如何来区分该调用哪个方法(csharpprogramer,cprogramer,javaprogramer)对程序员进行描述。
public void description(string programername, 某类型 某参数)
{
//调用对应的方法
}
这里的某类型就是要用它来区别哪个方法的类型,换句话说,最好就是在这里我直接把我想要调用的方法当做参数传进去。比如我要调用cprogramer方法来描述c程序员,
programerdescription pm = new programerdescription();
pm.description("d.m.ritchie", cprogramer);
按照这个想法,public string description(string programername, 某类型 某参数)的“某类型 某参数”该怎么表示呢?
当然我们就想到c#中的委托delegate了。委托是一种数据结构,它引用静态方法或引用类实例及该类的实例方法。 用委托来完成上述的代码:
public class programdescriptiondelegate { //委托,表示方法 public delegate void descriptiondelegate(string programername); //01 public void csharpprogramer(string programername) { console.writeline(string.format("{0} 使用c#编程!", programername)); } public void cprogramer(string programername) { console.writeline(string.format("{0}使用c语言编程!", programername)); } public void javaprogramer(string programername) { console.writeline(string.format("{0} 使用java语言编程!")); } //02 public void description(string programername, descriptiondelegate description) { description(programername); } }
调用:
programdescriptiondelegate pm = new programdescriptiondelegate(); pm.description("杨友山", pm.csharpprogramer);
结果是和最开始的代码是一样的。
什么是委托?msdn这样解释的:委托是一种定义方法签名的类型,可以与具有兼容签名的任何方法关联,可以通过委托调用方法。委托用于将方法作为参数传递给其他方法。时间处理程序就是通过委托调用的方法。
仔细看使用委托的代码,
public void description(string programername, descriptiondelegate description)。调用时,
descriptiondelegate description传入的是 pm.csharpprogramer,也就是此时description=pm.csharpprogramer。其实我们还可以这样调用:
//方法和委托绑定 programdescriptiondelegate pm = new programdescriptiondelegate(); yys.csharpstudy.window.sdelegate.programdescriptiondelegate.descriptiondelegate csharpdelegate = pm.csharpprogramer; yys.csharpstudy.window.sdelegate.programdescriptiondelegate.descriptiondelegate cdelegate = pm.cprogramer; pm.description("杨友山", csharpdelegate); pm.description("d.m.ritchie", cdelegate);
结果:
再做修改:
programdescriptiondelegate pm = new programdescriptiondelegate(); yys.csharpstudy.window.sdelegate.programdescriptiondelegate.descriptiondelegate pdelegate = null; pdelegate += pm.csharpprogramer; pdelegate += pm.cprogramer; pm.description("杨友山", pdelegate);
结果:
这里先执行了pm.csharpprogramer,然后又执行了pm.cprogramer方法。
可以看出委托不光可以将方法作为参数,而且还可以将方法绑定,而起还可以绑定多个。
使用+=绑定方法,取消则使用-=进行取消,上面的调用可以修改如下:
programdescriptiondelegate pm = new programdescriptiondelegate(); yys.csharpstudy.window.sdelegate.programdescriptiondelegate.descriptiondelegate pdelegate = null; pdelegate += pm.csharpprogramer; pdelegate += pm.cprogramer; pdelegate -= pm.cprogramer; pm.description("杨友山", pdelegate);
这样就只调用pm.csharpprogramer;一个方法了。
以上就是c#基础知识整理 基础知识(20) 委托(一)的内容。