• 胡乱写的一点利用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;所得的结果就不会是现在这样了。

  • 相关阅读:
    mybatis动态查询,模糊查询
    Python 列表
    异步加载实现点赞功能($.load 出现post不支持)
    shiro多账号登录(用户名,手机号,邮箱)
    spring data jpa 级联操作的时候注意事项
    semantic UI 点击按钮自动提交表单原因
    上线日期
    有关弱类型意识、DOM、动态语言与函数式编程
    视频项目时长的存储和程序设计方案---单例模式节省内存空间以及自定义注解
    项目中整合第三方插件与SpringMVC数据格式化关于ip地址
  • 原文地址:https://www.cnblogs.com/apodemakeles/p/1866256.html
Copyright © 2020-2023  润新知