浅谈如何使用 Lambda 表达式做抽象代表(2)
来源:学生作业帮助网 编辑:作业帮 时间:2024/09/02 09:14:37
浅谈如何使用 Lambda 表达式做抽象代表(2)
浅谈如何使用 Lambda 表达式做抽象代表(2)
浅谈如何使用 Lambda 表达式做抽象代表(2)
这两行代码也要求一对参数:一个用于文本的字符串和用于背景颜色的颜色刷.这意味着你需要使用的代表定义要考虑到这两个参数并返回无效值:Action updateTimer; 在声明变量后,你可以为代码指定需要执行的代表变量.这里你可以使用lambda表达式,因为Action是一个具体的代表定义:updateTimer = (label,newBrush) => { MyTime.Background = newBrush; MyTime.Content = label; }; 现在,当计时器提出事件时,你已经拥有了一些需要执行的指向该代码的变量.接下来要做的就只是通过Dispatcher.Invoke()使用代表定义:if (!MyTime.Dispatcher.CheckAccess()) { MyTime.Dispatcher.Invoke(updateTimer,newLabel,next); } else updateTimer(newLabel,next); 这一过程十分简单,但是却要求你反复进行,因此,我们可以让步骤变得容易一点.这里其实由一个简单的模式.事件处理器可以从背景线程中调用出来.当我们使用计时器,或者异步调用Web服务以及其他类似任务的时候,你就会看到这一行为.无论是在什么时候,我们都不清楚自己位于哪个线程之上,我们可以调用Dispatcher.CheckAccess()来决定是否可以访问任意用户界面控件.如果需要从线程边界执行调用,就必须使用Dispatcher.Invoke().Dispatcher.Invoke()方法避免了由于使用了方法参数的参数数组而造成的若干超载问题.它使用的是一个我们想要执行的抽象代表类型.你想要一个能检查是否需要整理编排的单一方法.如果需要,则方法会编排好调用,否则,会调用由代表指定的方法.你虚伪方法作为System.Windows.Controls.Control 类型的成员出现.这样使得你可以将代码作为控件的一部分来使用.C#3.0就为你提供了这样做的方法:扩展方法.你需要编写一些方法的不同超载,这些使得你可以通过不同的参数来使用它们:public static class WPFExtensions:{ public static voidInvokeIfNeeded( this Control widget,Action whatToDo) { if (!widget.Dispatcher.CheckAccess()) widget.Dispatcher.Invoke(whatToDo); else whatToDo(); } public static void InvokeIfNeeded( this Controlwidget,Action whatToDo,T parm) { if (!widget.Dispatcher.CheckAccess()) widget.Dispatcher.Invoke(whatToDo,parm); else whatToDo(parm); } public static void InvokeIfNeeded(this Controlwidget,Action whatToDo,T1 parm1,T2 parm2) { if (!widget.Dispatcher.CheckAccess()) widget.Dispatcher.Invoke(whatToDo,parm1,parm2); else whatToDo(parm1,parm2); } } 当然,我们也可以通过添加更多参数的方式来添加更多超载以扩展这个类.这其实是一个简单的扩展.有一种方法让WPF设计师们疯狂:他们希望用最小化应用程序接口的面积部分来简化Dispatcher对象的使用.通过使用抽象代表和参数列表中的参数,这一对象的使用范围被扩大了.任何带有参数的方法都可以被拿来使用.但是,这样做有一个不足之处.该应用程序接口更为抽象,它会破坏所有类型的安全性,而且这样做会损坏编译器使用类型推理的能力,从而降低工作效率.