知识大全 浅谈如何使用Lambda 表达式做抽象代表

Posted

篇首语:存储阳光,必有远芳;心中有暖,又何惧人生荒凉。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 浅谈如何使用Lambda 表达式做抽象代表相关的知识,希望对你有一定的参考价值。

浅谈如何使用Lambda 表达式做抽象代表  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  Lambda表达比代表定义和带外方法定义的结合更清楚 且相关的额外工作只需要满足语言定义即可 不过 它也有一些不足之处 如果某个方法的参数包含System Delegate 这样的抽象类型 用lambda表达式介绍特殊的问题 C#编译器不能将lambda表达式转换成还未明确定义的衍生代表类型

  如果不仔细思考一下 你的代码看上去就会像是来自 NET 的东西 在本文中 我将告诉告诉你为什么lambda表达式不足以被直接转换成抽象代表类型 并且教你怎样使得编译器转换你所定义的指定代表 解决方案依赖于Windows Presentation Foundation(WPF)和System Windows Threading Dispatcher组件 但是严格意义上说 该问题不是一个WPF问题 文中所描述的问题出现在若干 NET框架中 包括Windows Forms Office 应用程序接口和映射应用程序接口 你可以按照下列方法来处理同类问题

  无论我什么时候使用 NET框架中带有来自代表表格的参数的应用程序接口 我都会倾向于使用lambda表达式而不是更详细的表达式 例如 这行代码创建了一个System Windows Threading Timer 在计时器失效时 该代码调用了一个TickHandler方法

  tick = new System Threading Timer((unused) =>

  TickHandler());

  如果方法的内容足够少 我就会用方法的内容替代TickHandler()方法调用 该方法大多数情况下都有效 但是当应用程序接口将System Delegate作为参数时 这一技巧不管用 例如 我们将System Windows Controls Dispatcher Invoke()方法穿过WPF中的线程实施调用

  public object Invoke(

  delegate method

  params object[] args)

  现在考虑一下当我们尝试用lambda表达式来执行这样的调用时 将会发生什么

  MyTime Dispatcher Invoke(() => DoSomething());

  会出现隐秘错误

  error CS : Cannot convert lambda expression to

  type System Delegate because it is not a delegate type

  或许第一次看到这个错误的时候 你还不知道到底是怎么一回事 当然 这的确是一个代表类型 编译器不像人一样的灵活 System Delegate类型是一个抽象类型 且该类型的推理工具不能推断出自变量或某些用于未知代表类型的返回值的数量和种类 要解决这一问题 我们必须创建一个具体的代表类型并为该类型指定lambda表达式 记住 代表类型要求你将方法视为数据

  我创建了一个WPF计时器程序来展示其工作原理 其中阐述了C# 怎样简化与老式应用程序接口(下图)的运行

  当你做演示的时候 该示例中的应用程序运行了一个计时器 随着设定时间流逝 它的颜色会从绿色转为黄色再转为红色 这是一个很好的演示跨线程调用的方法 因为该计时器在背景线程中运行

  按照时间的改变来更新演示要求对出自计时器的事件作出响应 计时器在背景线程中运行 所以你会很轻易地犯我们在前面提到过的错误

  更新应用程序

  用户界面处理的是简单代码 当计时器失效时它会生效 而且代码会更新计时器的显示 这一更新必须改变文本 或控制背景 如下所示

  MyTime Background = newBrush;

  MyTime Content = label

  计时器在背景线程上运行 所以你需要通过使用Dispatcher Invoke()边界线执行调用 这两行代码是你想列入lambda表达式的代码 不是证明方法定义的逻辑理由 但是我之前就讲过lambda不会与Didpatcher Invoke一起运行 除非是你使用了具体的代表定义才行 这之中的一部分已经在 NET框架 中定义了  

  我们可以使用嵌入式代表定义并对它们进行分配 这些都是的该解决方案比起先前提到过的案例都要省事一些 这两行代码也要求一对参数 一个用于文本的字符串和用于背景颜色的颜色刷 这意味着你需要使用的代表定义要考虑到这两个参数并返回无效值

  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# 就为你提供了这样做的方法 扩展方法 你需要编写一些方法的不同超载

  这些使得你可以通过不同的参数来使用它们

  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

  T parm T parm )

  

  if (!widget Dispatcher

  CheckAccess())

  widget Dispatcher

  Invoke(whatToDo

  parm parm );

  else

  whatToDo(parm parm );

  

  

  当然 我们也可以通过添加更多参数的方式来添加更多超载以扩展这个类 这其实是一个简单的扩展

  有一种方法让WPF设计师们疯狂 他们希望用最小化应用程序接口的面积部分来简化Dispatcher对象的使用 通过使用抽象代表和参数列表中的参数 这一对象的使用范围被扩大了

  任何带有参数的方法都可以被拿来使用 但是 这样做有一个不足之处 该应用程序接口更为抽象

cha138/Article/program/net/201311/12838

相关参考

知识大全 Lambda表达式的一般应用

.Net基础:Lambda表达式的一般应用  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  在Li

知识大全 Lambda表达式的一般应用

Lambda表达式的一般应用  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  在List中实现Fi

知识大全 Linq入门演练:lambda表达式

Linq入门演练:lambda表达式  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  今天大家一同

知识大全 .Net基础Lambda表达式的一般应用教程

.Net基础Lambda表达式的一般应用教程  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  在L

知识大全 探索Java语言与JVM中的Lambda表达式

探索Java语言与JVM中的Lambda表达式  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  L

知识大全 Java8和Scala中的Lambda表达式

Java8和Scala中的Lambda表达式  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!&nbs

知识大全 构建用于正则表达式的抽象Java API

构建用于正则表达式的抽象JavaAPI  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  在我的经验

行政行为依行为对象做标准可以分为具体行政行为和抽象行政行为

行政行为依行为对象做标准可以分为具体行政行为和抽象行政行为。_____答案:错误解析:依行为对象是否特定为标准,注意重心在是否特定上。

知识大全 Lambda

从根本上改变我们开发Java程序的方式:Lambda  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

知识大全 从Lambda到Object

闭包工厂模式:从Lambda到Object  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  下面的