• 【fixed point】柯里化(currying) C#实现


    参考文章:http://www.mamicode.com/info-detail-1076478.html

    函数调用的演变:

     /// <summary>
        /// 柯里化的演变
        /// </summary>
        public class Currying
        {
            CurryingSdkApi api = new CurryingSdkApi();
    
            public string callApi()
            {
                var result = string.Empty;
    
    
                //假如现在我们基于某个sdk开发一个app,需要调用该sdk提供的api,这些api都有3个参数,分别是调用你的app的id,用户的id和用户的nickname
                result = api.SdkApiFirst("myApp", "xiaoming", "小明");
                result = api.SdkApiFirst("myApp", "xiaohong", "小红");
                result = api.SdkApiFirst("myApp", "xiaogang", "小刚");
    
                //这时候你可能发现了一些端倪,代码中出现了重复的部分(你的app的id),这时候重构代码把公共的部分抽取出来,你可能会这么封装
                result = MyApiFirst("xiaoming", "小明");
                result = MyApiFirst("xiaohong", "");
                result = MyApiFirst("xiaogang", "小刚");
    
                //然后你继续开发,发现要调用另外一个api,这个api跟上面那个很相似,只是第2、3个参数变为了用户的令牌和用户id。因为你的app的id是不变的,有了之前的经验,你或许会这么封装。
                result = MyApiSecond(1, "xiaoming");
                result = MyApiSecond(2, "xiaohong");
                result = MyApiSecond(3, "xiaogang");
    
                //继续开发的时候,你很有可能会继续调用类似的api3,api4,api5......,这些api的第一个参数都是你的app的id,而在你的某个项目里面,这都是固定不变,那么你的程序里面会出现类似的封装,可以看出又有了重复的代码
                //此时你或许会这么封装去减少重复
    
                var myapi1 = api.SdkApiSeriesFirst(api.SdkApiFirst);
                result = myapi1(string.Empty, "xiaoming", "小红");
    
                var myapi2_1 = api.GetMyDefaultApi<string, string, string>(api.SdkApiFirst);
                result = myapi2_1("xiaoming", "小红");
    
                var myapi2_2 = api.GetMyDefaultApi<int, string, string>(api.SdkApiSecond);
                result = myapi2_2(2, "xiaogang");
    
                var myapi3 = api.SdkApiSeriesFirstPlus(api.SdkApiFirst);
                result = myapi3("xiaoming", "小红");
    
    
                return result;
            }
    
            public string MyApiFirst(string userId, string nickname)
            {
                return api.SdkApiFirst("myApp", userId, nickname);
            }
    
            public string MyApiSecond(int token, string userId)
            {
                return api.SdkApiSecond("myApp", token, userId);
            }
        }

    假设的API接口:

     public class CurryingSdkApi
        {
            /// <summary>
            /// 软件开发工具包(第一个API)
            /// </summary>
            /// <param name="appId"></param>
            /// <param name="userId"></param>
            /// <param name="nickname"></param>
            /// <returns></returns>
            public string SdkApiFirst(string appId, string userId, string nickname)
            {
                return "SdkApiFirst " + appId + userId + nickname;
            }
    
    
            /// <summary>
            /// 软件开发工具包(第二个API)
            /// </summary>
            /// <param name="appId"></param>
            /// <param name="token"></param>
            /// <param name="userId"></param>
            /// <returns></returns>
            public string SdkApiSecond(string appId, int token, string userId)
            {
                return "SdkApiSecond " + appId + token + userId;
            }
    
    
            public Func<string, string, string, string> SdkApiSeriesFirst(Func<string, string, string, string> f)
            {
                return (x, y, z) => f("myApp", y, z);
            }
    
    
            public Func<string, string, string> SdkApiSeriesFirstPlus(Func<string, string, string, string> f)
            {
                return (x, y) => f("myApp", x, y);
            }
    
            public Func<string, string> SdkApiSeriesSecond(Func<string, string, string, string> f)
            {
                return (x) => f("myApp", "myAppName", x);
            }
    
            public Func<T1, T2, TResult> GetMyDefaultApi<T1, T2, TResult>(Func<string, T1, T2, TResult> f)
            {
                return (x, y) => f("myApp", x, y);
            }
        }

    关键点:

    下面是匿名函数,  a,b 是 参数

    (a,b) => {  实现方法内容  };

     可以,封装一个三个参数的方法为两个参数的方法

     public Func<string, string, string, string> SdkApiSeriesFirst(Func<string, string, string, string> f)
            {
                return (x, y, z) => f("myApp", y, z);
            }
  • 相关阅读:
    追随自己的价值观:用研经理 Anne Diaz 职业探索之路
    语义化版本(SemVer)的范围
    git如何放弃所有本地修改
    将本地已有的一个项目上传到新建的git仓库的方法
    using supervisord to run lsyncd script
    sersync下载安装及配置(有演示示例)
    sersync+rsync原理及部署
    Rsync+sersync 实现数据实时同步
    在分屏浏览中并排使用两个 Mac App
    MacOS 安装 Astah Professional 7.2
  • 原文地址:https://www.cnblogs.com/FH-cnblogs/p/6914037.html
Copyright © 2020-2023  润新知