C#委托delegate
2013-05-11 18:40 hduhans 阅读(243) 评论(0) 收藏 举报一、初级版,有了委托呢,我们就可以像传递变量一样的传递方法。在JavaScript,PHP等弱类型语言中,本身就支持方法作为另一方法的参数进行传递。
1) 参考代码:
public class Program { public delegate void delegateGreeting(String name); //定义个方法委托 该委托支持调用具有相同参数的方法
//此处可用Func委托简化使用,
//public static void GreetPeople(String name,Func<String,String> fun)
//{ fun(name); }
public static void GreetPepole(String name, delegateGreeting MakeGreeting) { MakeGreeting(name); } public static void EnglishGreeting(String name) { Console.WriteLine("Moring," + name); } public static void ChineseGreeting(String name) { Console.WriteLine("你好," + name); } static void Main(string[] args) { GreetPepole("hans", EnglishGreeting); GreetPepole("小刚", ChineseGreeting); Console.Read(); } }
可以看出,委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性。
2) 使用委托可以将多个方法绑定到同一个委托变量,调用多个方法
static void Main(string[] args) { delegateGreeting de; de = EnglishGreeting; de += ChineseGreeting; GreetPepole("hans", de); //委托对象按顺序调用两个两个方法 Console.Read(); }
二、高级版。观察者设计模式通常使用使用委托和事件。这有一个热水器、监视器、警报器的应用案例,给热水器通上电,当水温超过95度时,监视器显示水温,警报器发出警报,提示水快烧开了。
//热水器 public class Heater { private int temperature; public string type = "my type"; public string area = "China Hangzhou"; //声明委托 命名规则 以Eventhandler结尾 public delegate void BoiledEventHandler(Object sender, BoiledEventArgs e); //声明事件 命名规则 以Event结尾 public event BoiledEventHandler BoiledEvent; public class BoiledEventArgs : EventArgs { public readonly int temperature; public BoiledEventArgs(int temperature) { this.temperature = temperature; } } protected virtual void OnBoiled(BoiledEventArgs e) { if (BoiledEvent != null) { BoiledEvent(this,e); } } //烧水 public void BoilWater() { for (int i = 0; i <= 100; i++) { temperature = i; if (temperature > 95) { BoiledEventArgs e = new BoiledEventArgs(temperature); OnBoiled(e); } } } } //警报器 public class Alarm { public void MakeAlert(Object sender, Heater.BoiledEventArgs e) { Heater heater = (Heater)sender; Console.WriteLine("Alarm:{0}-{1}",heater.area,heater.type); Console.WriteLine("Alarm:嘀嘀嘀,水已经{0}度",e.temperature); Console.WriteLine(); } } //监视器 public class Display { public void ShowMsg(Object sender, Heater.BoiledEventArgs e) { Heater heater = (Heater)sender; Console.WriteLine("Display:{0}-{1}",heater.area,heater.type); Console.WriteLine("Display:水快烧开了,当前水温{0}度",e.temperature); Console.WriteLine(); } } //...使用方法 Heater heater = new Heater(); heater.BoiledEvent += new Heater.BoiledEventHandler((new Alarm()).MakeAlert); heater.BoiledEvent += (new Display()).ShowMsg; heater.BoilWater();
三、申明委托
1) delegate。至少0个参数,参数个数[0~32],返回值可有可无。如:public delegate int deleteAdd(int x,int y);
注意到,在delegate委托定义中,最重要的是参数类型(int x,int y)和返回值(int),由此引入了下面的委托简写。
2) Action,Action表示无返回值的泛型委托,参数个数[0~16]。
a、Action 表示无参,无返回值的委托;
b、Action<int,int> 表示传入参数int,int无返回值的委托;
3) Func,Func表示有返回值的泛型委托,最后一个参数为返回值,参数个数[0~16]。
a、Func<int> 表示无参,返回值为int的委托;
b、Func<int,String> 表示传入参数int,返回值为String的委托;
c、委托与匿名方法,定义如:Func<String,String> fun = delegate(String s){ return s.ToUpper(); }
d、委托与lambda表达式,定义如:Func<String,String> fun = x=>x.ToUpper(); --普通lambda表达式
或 Func<String,String> fun = x=>{ Console.WrieLine(x); }; --定义方法
4) predicate,表示返回bool类型的泛型委托。predicate有且只有一个参数,返回值固定为bool,参数个数[1];
C#函数之惰性求值
http://www.cnblogs.com/yaozhenfa/p/functional_lazy.html
浙公网安备 33010602011771号