*委托与事件
* 当我们需要把方法传递给另一个方法时,我们就需要使用委托
* 一般来说如果我们不能直接对一个数据或者机构进行比较时,就得需要委托去寻找适合进行比较的方法
* 委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,
* 可以避免在程序中大量使用If … Else(Switch)语句,同时使得程序具有更好的可扩展性。
*
*
* 结构示例 delegate void IntMethodInvoker(int x);
* 关键字 返回 方法名 参数
* delegate string newfuction() ;
* 委托是类型,就能被定义
* newfuction func = new newfuction(方法);
* 也可以 newfunction func = 类.属性方法
* 使用委托时,就像使用方法一样 func(param);
*
* action<T>委托,允许带有多个参数,但是没有返回值
* Func<T>委托,允许带有多个参数,而且有一个返回值
*
* 多播委托,委托包含多个方法,可以按照顺序连续调用多个方法
* 多播委托可以识别+,-,+=,-=号,只要将方法相加或者相减即可在委托中添加方法和删除方法
* 多播委托的缺点,当抛出某个异常时,就会停止整个迭代。
*
*
* lambda 表达式
* 用于把实现代码赋予给委托
* lambda 运算符“=>” 左边列出需要的参数,右边定义赋予lambda变量的方法的实现代码
*
* 事件基于委托,为委托提供了一种发布/订阅机制
* 通知事件发生的,就是发布者
* 对某件事情关注的,就是订阅者
* 事件发生时,会通知所有关注该事件的订阅者,
* 想在事件发生时被通知,就必须注册以表示关注
*
* 事件发生时,通知订阅者,就是调用订阅者的注册函数。注册,就是告诉发布者调用哪一个注册函数
* 事件生命 delegate void HandLer();
* public event Handler NewDog;
* 委托类型 事件名
* 关注 就是委托添加 注册方法
* 取消订阅 就是委托删除 注册方法
*
* 事件类似于封装的委托,只有+=和-=操作
*
*
* 事件步骤
* 1.在需要监听事件的类,添加委托delegate handler(名称最好用handler结尾),参数与想要绑定的方法相同
* 2.在这个类中,声明一个public event (delegate名称);
* 3.在触发事件的地方,先判断事件是否存在。然后触发event(委托中的参数);
* 4,在main方法中,创建触发事件的类的对象和需要订阅事件的类的对象,将他们的方法绑定在委托上。
* 5.触发事件,订阅者就能接收事件信息
*/
class Consumer
{
public void WantAdog()
{
Console.WriteLine("get message");
}
}
class Program
{
private delegate string GetAString();
//代理创建时,要保持与想要传递方法的参数和返回值的一致
delegate double DoubleOP(double x);
static void Main(string[] args)
{
int x = 40;
GetAString firstString = new GetAString(x.ToString);
Console.WriteLine("string is {0}", firstString());
//创建一个委托数组,包含两个委托,一个委托是 DoubleOP = MathOperations.MultiplyByTwo 另一个委托是 DoubleOP = MathOperations.square
DoubleOP[] operations = {
MathOperations.MultiplyByTwo,
MathOperations.square };
//func<t>委托
Func<double, double>[] Foperations={
MathOperations.MultiplyByTwo,
MathOperations.square };
for (int i = 0; i < operations.Length; i++)
{
Console.WriteLine("using operations "+ i);
ProcessAndDisplayNumber(operations[i],2.0);
ProcessAndDisplayNumber(operations[i], 7.94);
ProcessAndDisplayNumber(operations[i], 1.414);
//使用fucn委托
FProcessAndDisplayNumber(Foperations[i],5.5);
}
Employee[] employees = { new Employee("bob",545), new Employee("angle", 78965), new Employee("dd", 95641), new Employee("cc", 555), new Employee("ee", 7854311) };
//传入泛型数组,以及func委托
BuddleSorter.sort(employees,Employee.compareToSarlay);
foreach (var employee in employees )
{
Console.WriteLine(employee);
}
// 多播委托的缺点,当抛出某个异常时,就会停止整个迭代。
Action d1 = one;
d1 += two;
try
{
d1();
}
catch (Exception)
{
Console.WriteLine("stopped");
}
//使用新方法,可以防止抛出异常后停止
Delegate[] delegates = d1.GetInvocationList();
foreach (Action d in delegates)
{
try
{
d();
}
catch (Exception)
{
Console.WriteLine("catch exception");
}
}
//lambda 表达式
Func<string, string> lambda = param =>
{
param = "firstPart ";
param += "and this part";
return param;
};
Console.WriteLine(lambda("123"));
//多个参数的lambda表达式
Func<double, double,double> test = (z, y) =>
{
return z * y;
};
Console.WriteLine(test(5.5,6.6));
var values = new List<int>() { 10,20,30};
var funcs = new List<Func<int>>();
foreach (var value in values)
{
//实际上就是给委托添加lambda 语句添加一个无参的,返回值为Value的lambda 语句 list中的func<int> =()=>value
funcs.Add(()=>value );
}
foreach (var f in funcs)
{
Console.WriteLine(f());
}
//事件
Consumer c1 = new Consumer();
Consumer c2 = new Consumer();
//注册
Dog.NewDog += c1.WantAdog;
Dog.NewDog += c2.WantAdog;
Dog dog = new Dog("qqq");
//汽车事件
//先创建汽车经销商
var dealer = new CarDealer();
//再创建顾客
var michael = new Consumers("michael");
//为顾客订阅汽车经销商的事件
dealer.NewCarInfo += michael.NewCarIsHere;
//汽车经销商发动事件
dealer.NewCar("Ferrari");
//创建一个新的客户
var sebastian = new Consumers("sebastian");
//为新客户订阅汽车经销商的事件
dealer.NewCarInfo += sebastian.NewCarIsHere;
//汽车经销商再发动事件
dealer.NewCar("Mercedes");
//为michael客户取消订阅事件
dealer.NewCarInfo -= michael.NewCarIsHere;
//汽车经销商再发动事件
dealer.NewCar("red Bull Racing");
//自己写一个事件通知例子
//有一个超市market ,他会不时地引进一些新产品,有一些学生,很喜欢这个超市的东西,希望有新产品的时候,就能第一时间接到通知,这个通知由超市经理来发送
//创建一个叫做bob的经理
MarketManager manager = new MarketManager("Bob");
Student student1 = new Student("Angle");
manager.marketInfo += student1.getInfomation;
manager.GetNewProduct("milk");
Student student2 = new Student("Ben");
manager.marketInfo += student2.getInfomation;
manager.GetNewProduct("PS4");
manager.marketInfo -= student2.getInfomation;
manager.GetNewProduct("meat");
Heater he = new Heater();
Display dis = new Display();
he.Event += dis.MakeAlert;
he.Event += Alarm.ShowMessage;
he.Event += (new Display()).MakeAlert;
he.BoilWater();
}
static void one()
{
Console.WriteLine("1");
throw new Exception("test");
}
static void two()
{
Console.WriteLine("two");
}
static void ProcessAndDisplayNumber(DoubleOP action, double value)
{
double result = action(value);
Console.WriteLine("value is "+ value + " result is " + result);
}
//使用func委托
static void FProcessAndDisplayNumber(Func<double,double> action, double value)
{
double result = action(value);
Console.WriteLine("Using Func delegate ->value is " + value + " result is " + result);
}
}
//创建一个类,包含两个静态方法
class MathOperations
{
public static double MultiplyByTwo(double value)
{
return value * 2;
}
public static double square(double value)
{
return value * value;
}
}
部分代码参考 http://www.cnblogs.com/SkySoot/archive/2012/04/05/2433639.html 也是委托与代理
这些是主要代码,其他类代码比较多,就不一一贴上来了,我已上传到github,有需要的可以去下载运行一下
github链接是:https://github.com/lcxxxc/UWP_Readness study_day3_part_two 部分
还有一些委托和事件的练习,名字叫做 delegateandeventTest的部分
如果有什么不对,欢迎评论。