zoukankan      html  css  js  c++  java
  • 胡乱写的一点利用C#中闭包模拟OOP的代码

    先来看一段JS代码:

    function Outer()
    {
     var count = 0;
     var Inner = function(){
      alert(count++);
     }
     return Inner;
    }
    
    var f = Outer();
    var k = Outer();
    f();
    f();
    k();
    f();
    k();
    

    这就是JS中最简单的闭包实现,可以类似对象的操作,以函数的形式内聚一些数据.

    我们知道C#中是支持闭包的,一个方法(函数)引用了其作用域以外的变量,进行操作.具体实现原理可以自己用IL或者找些文章来了解.

    那如果一个OOP的语言,使用FP的特性,再来模拟出OOP的特性,那真是吃饱了撑的,不过肯定好玩.

    今天学习了这篇文章 http://www.cnblogs.com/weidagang2046/archive/2010/11/01/1865899.html,照葫芦画瓢写了几行代码,全为了加深理解.

    先写一个最简单的类

    代码1
    1 public class OOPer
    2 {
    3 private int count = 0;
    4
    5 public void Say()
    6 {
    7 Console.WriteLine(count++);
    8 }
    9
    10 public void Reset()
    11 {
    12 count = 0;
    13 Console.WriteLine("Have Reset");
    14 }
    15
    16 public void Set(int newcount)
    17 {
    18 count = newcount;
    19 Console.WriteLine("Set");
    20 }
    21 }

    你可以实现此类若干事例,不断调用Say,Set,Reset方法。那如果使用闭包的形式会是怎样的?

    代码2
    1 public class FPer
    2 {
    3 Func<FPerMethod, object> fpfunc = null;
    4
    5 public FPer()
    6 {
    7 fpfunc = GetClosure();
    8 }
    9
    10 public void Say()
    11 {
    12 Action act = fpfunc(FPerMethod.Say) as Action;
    13 act();
    14 }
    15
    16 public void Reset()
    17 {
    18 Action act = fpfunc(FPerMethod.Reset) as Action;
    19 act();
    20 }
    21
    22 public void Set(int newcount)
    23 {
    24 Action<int> act = fpfunc(FPerMethod.Set) as Action<int>;
    25 act(newcount);
    26 }
    27
    28 private enum FPerMethod
    29 {
    30 Say,
    31 Reset,
    32 Set
    33 }
    34
    35 /// <summary>
    36 /// 使用不同的枚举类型作为参数,选择返回不同的操作方法
    37 /// </summary>
    38 /// <returns></returns>
    39   private Func<FPerMethod, object> GetClosure()
    40 {
    41 int count = 0;
    42
    43 Func<FPerMethod, object> func =
    44 (method) =>
    45 {
    46 if (method == FPerMethod.Say)
    47 {
    48 Action act = () => { Console.WriteLine(count++); };
    49 return act;
    50 }
    51 else if (method == FPerMethod.Reset)
    52 {
    53 Action act = () =>
    54 {
    55 count = 0;
    56 Console.WriteLine("Have Reset");
    57 };
    58 return act;
    59 }
    60 else if (method == FPerMethod.Set)
    61 {
    62 Action<int> act = (c) =>
    63 {
    64 count = c;
    65 Console.WriteLine("Set");
    66 };
    67
    68 return act;
    69 }
    70
    71 return null;
    72 };
    73
    74 return func;
    75 }
    76 }

    使用方式和OOper一模一样,只要new一个FPer,就可以使用了。其核心就是GetClosure(),相当于一个FactoryMothed,每次Create一个用闭包是实现的特殊对象,又像是一个对象,因为你所使用核心数据count也是在它的作用域中。所以,如果你把 Action act = fpfunc(FPerMethod.Say) as Action;换成了Action act = GetClosure()(FPerMethod.Say) as Action;所得的结果就不会是现在这样了。

  • 相关阅读:
    ubuntu16.04安装opencv3.4.0
    基于flask+gunicorn+nginx来部署web App
    ubuntu更换pip install,apt-get,conda install 成国内源
    Ubuntu16.04安装编译caffe以及一些问题记录
    Tutorial for MI5 ! flash MI5 to Native Anriod 9
    在服务器上实现SSH(Single Stage Headless)
    .NET Core容器化开发系列(一)——Docker里面跑个.NET Core
    .NET Core容器化开发系列(零)——计划
    基于.NET Standard的分布式自增ID算法--美团点评LeafSegment
    基于.NET Standard的分布式自增ID算法--Snowflake代码实现
  • 原文地址:https://www.cnblogs.com/apodemakeles/p/1866256.html
Copyright © 2011-2022 走看看