知识大全 从Lambda到Object

Posted 函数

篇首语:见强不怕,遇弱不欺。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 从Lambda到Object相关的知识,希望对你有一定的参考价值。

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

  下面的这段C# 代码看似再普通不过

  Stack stack = StackFactory New();

  stack Push( );

  stack Push( );

  stack Push( );

  Console WriteLine(stack Pop());

  Console WriteLine(stack Pop());

  Console WriteLine(stack Pop());

  运行结果

  >>

  >>

  >>

  但如果我告诉你Stack并不是一个普通的class Stack 而是一个类型别名 using Stack = System Func<T R > 它其实是一个委托 你会不会觉得很神奇?说得更清楚一些 StackFatory New()所创建的不是一个普通对象 而是创建了一个闭包(Closure)

  闭包是什么?

  那么闭包究竟是什么呢?目前有两种流行的说法 一种说法是闭包是在其词法上下文中引用了自由变量的函数 另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体 两种说法都对 但我更倾向于第二种表述 因为它明确地将闭包定义为 实体 从例子中我们可以看出 闭包可以表现出对象的特征 而普通的lambda函数或delegate更像是某个方法 结合两种定义 我认为可以把闭包理解为带状态的函数

  自由变量

  我们先来看一个闭包的简单例子

  static Func<int int> AddX(int x)

  return (y) => x + y;

  

  这里的lambda函数(y) => x + y就是一个闭包 它引用了其词法上下文之外的自由变量x 对AddX( )求值将用 代换x 即(y)=> + y 若再继续求值AddX( )( )将得到 + =

  状态

  下面我们将看到如何使闭包具有状态

  static Func<int> NewCounter()

  int x = ;

  return () => ++x;

  

  Func<int> counter = NewCounter();

  Console WriteLine(counter ());

  Console WriteLine(counter ());

  Console WriteLine(counter ());

  Func<int> counter = NewCounter();

  Console WriteLine(counter ());

  Console WriteLine(counter ());

  Console WriteLine(counter ());

  运行结果

  >>

  >>

  >>

  >>

  >>

  >>

  我们通过NewCounter创建了一个闭包 每次对闭包进行求值都会使其环境的局部变量x增 这样就体现了闭包的状态 同时 我们注意到局部变量x对于不同的闭包是独立的 counter 和counter 并不共享同一个x

  闭包 vs class

  这里我们可以和OOP程序做一个对比 如果要用类来实现Counter我们会怎么做呢?

  class Counter //对应NewCounter

  private int x; //对应局部变量int x

  public Counter() x = ; //new Counter()对应NewCounter()

  public int Count() return ++x; //对应() => ++x

  

  和 上面的闭包程序相比 从结构上看是不是有些类似呢?Counter类与NewCounter函数对应 new Counter()与NewCounter()对应 Counter类的私有成员x和NewCounter的局部变量x对应 Counter类的 Count()方法与闭包对应

  行为

  除了状态 我们还需要让闭包具备类似stack Push()和stack Pop()这样的对象行为 由于闭包只拥有一个()运算符 需要怎样做才能使其具有多个方法呢?答案是高阶函数(Higher Order Function) 看刚才Stack的例子

  public enum Method

  Push Pop Top

  

  public static Func<Method object> New()

  LinkedList<int> aList = new LinkedList<int>();

  Func<Method object> func = (method) =>

  switch (method)

  case Method Push:

  Action<int> push = (int aValue) => aList AddLast(aValue); ;

  return push;

  case Method Pop:

  Func<int> pop = () =>

  int value = aList Last Value;

  aList RemoveLast();

  return value;

  ;

  return pop;

  case Method Top:

  Func<int> top = () => return aList Last Value; ;

  return top;

  default:

  return null;

  

  ;

  return func;

  

  NewStack()返回的是一个Func<Method object>类型的闭包 它的参数是enum Method类型的 返回值是object NewStack()(Method Push)将得到

  Action<int> push = (int aValue) => aList AddLast(aValue); ;

  这就是实际的Push方法!不过 在调用之前还需要显式转换一下类型

  (NewStack()(Method Push) as Action<int>)( );

  最后 我们利用C# 的扩展方法(Extension Method)包装一下 让这个调用更加简洁

  public static void Push(this Func<Method object> aStack int aValue)

  (aStack(Method Push) as Action<int>)(aValue);

  

  public static int Pop(this Func<Method object> aStack)

  return (int)(aStack(Method Pop) as Func<int>)();

  

  public static int Top(this Func<Method object> aStack)

  return (int)(aStack(Method Top) as Func<int>)();

  

  这样 我们就能写出stack Push( ) stack Pop()这样很OO的代码来了!通过这样一步步地探索 不知道您是否对函数式编程的闭包以及它和OOP对象的关系有了更深的理解呢?

  模式

  我们可以把上面在C# 中用闭包创建对象的方法归纳为一种固定的模式 不妨称其为闭包工厂模式(Closure Factory Pattern) 模式要点包括

   定义一个工厂类XXFactory 提供创建闭包对象的静态工厂方法New

   在New方法的内定义局部对象作为闭包对象的状态m_States

   定义enum Method表示对象所具有的方法

   在New方法内创建并返回一个引用m_States的闭包closureObject 其类型为Func<Method object>

   closureObject接受Method参数 返回表示该方法的闭包(或普通委托)的methodObject

cha138/Article/program/ASP/201311/21828

相关参考

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

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

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

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

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

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

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

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

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

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

知识大全 .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

知识大全 Spring中的Object/XML映射详解

Spring中的Object/XML映射详解  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!&nbs

知识大全 Java程序性能优化-Value Object模式(1)[2]

Java程序性能优化-ValueObject模式(1)[2]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看