//定义委托,代表方法的类型
public delegate void GreetingDeleagte(string name);
public delegate void GreetingDeleagte1(string name);
public partial class weituo : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string name1, name2;
name1 = "张sdf";
name2 = "zhangdf";
/*写法一
委托GreetingDelegate 和 类型 string 的地位一样,都是定义了一种参数类型,也可以这么使用委托 */
GreetingDeleagte deleagte1, deleagte2;
deleagte1 = EnglishGreeting;
deleagte2 = ChineseGreeting;
GreetPeople(name1, deleagte1);
GreetPeople(name2, deleagte2);
/*写法二
1.委托不同于string的一个特性:可以将多个方法赋给同一个委托,或者叫将多个方法绑定到同一个委托,
当调用这个委托的时候,将依次调用其所绑定的方法
2.注意这里,第一次用的“=”,是赋值的语法;
第二次,用的是“+=”,是绑定的语法。如果第一次就使用“+=”,将出现“使用了未赋值的局部变量”的编译错误
*/
GreetingDeleagte delegates;
delegates = EnglishGreeting; // 先给委托类型的变量赋值
delegates += ChineseGreeting; // 给此委托变量再绑定一个方法
// 将先后调用 EnglishGreeting 与 ChineseGreeting 方法
GreetPeople("Jimmy Zhang", delegates);
/* 上面的写法是否能用下面的写法代替,答案是否定的!
GreetingDelegate delegate1 = new GreetingDelegate();
delegate1 += EnglishGreeting; // 这次用的是“+=”,绑定语法。
delegate1 += ChineseGreeting; // 给此委托变量再绑定一个方法
但实际上,这样会出现编译错误: “GreetingDelegate”方法没有采用“0”个参数的重载。
尽管这样的结果让我们觉得有点沮丧,但是编译的提示:“没有0个参数的重载”再次让我们联想到了类的构造函数。
我知道你一定按捺不住想探个究竟,但再此之前,我们需要先把基础知识和应用介绍完。
*/
/*写法三 */
GreetingDeleagte delegate3 = new GreetingDeleagte(EnglishGreeting);// 相当于 先给委托类型的变量赋值
delegate3 += ChineseGreeting; // 给此委托变量再绑定一个方法
// 将先后调用 EnglishGreeting 与 ChineseGreeting 方法
GreetPeople("Jimmy Zhang", delegate3);
Console.WriteLine();
delegate3 -= EnglishGreeting; //取消对EnglishGreeting方法的绑定
// 将仅调用 ChineseGreeting
GreetPeople("张子阳", delegate3);
/*总结:
1: 委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,
这种将方法动态地赋给参数的做法,可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性。
2.使用委托可以将多个方法绑定到同一个委托变量,当调用此变量时(这里用“调用”这个词,
是因为此变量代表一个方法),可以依次调用所有绑定的方法
3.委托GreetingDelegate出现的位置与 string相同,string是一个类型,那么GreetingDelegate应该也是一个类型,或者叫类(Class)。
但是委托的声明方式和类却完全不同,这是怎么一回事?
实际上,委托在编译的时候确实会编译成类。因为Delegate是一个类,所以在任何可以声明类的地方都可以声明委托。
*/
}
//它接受一个 GreetingDeleagte 类型的 *方法* 作为参数
public void GreetPeople(string name,GreetingDeleagte MakeGreeting)
{
MakeGreeting(name);
}
public void EnglishGreeting(string name)
{
Response.Write("Morning:"+name);
}
public void ChineseGreeting(string name)
{
Response.Write("你好:"+name);
}
}
}
/* 缺点:
*
* 尽管这样解决了问题,但我不说大家也很容易想到,这个解决方案的可扩展性很差,
* 如果日后我们需要再添加韩文版、日文版,就不得不反复修改枚举和GreetPeople()方法,以适应新的需求。
//定义枚举判断类型
public enum Language {
Engilsh,Chinese
}
public void GreetPeople(string name,Language lang)
{
switch (lang)
{
case Language.Engilsh:
EnglishGreeting(name);
break;
case Language.Chinese:
ChineseGreeting(name);
break;
}
}
public void EnglishGreeting(string name)
{
Response.Write("Morning:"+name);
}
public void ChineseGreeting(string name)
{
Response.Write("你好:"+name);
}
*/