您好,欢迎光临有路网!
C#函数式编程(第2版)
QQ咨询:
有路璐璐:

C#函数式编程(第2版)

  • 作者:(美)恩里科·博南诺(Enrico Buonanno) 著 张骏温 译
  • 出版社:清华大学出版社
  • ISBN:9787302633341
  • 出版日期:2023年06月01日
  • 页数:0
  • 定价:¥128.00
  • 分享领佣金
    手机购买
    城市
    店铺名称
    店主联系方式
    店铺售价
    库存
    店铺得分/总交易量
    发布时间
    操作

    新书比价

    网站名称
    书名
    售价
    优惠
    操作

    图书详情

    内容提要
    函数式编程将改变你思考代码的方式!利用良好的FP技术,C#开发人员可极大地提升软件的并发处理、状态管理和事件处理能力,以及软件的可维护性。本书介绍了在C#编码实践中添加函数式编程的原因、方式和位置。 《C#函数式编程(第2版)》引导你在C#语言中使用函数式思想来解决实际问题。书中回顾了C#语言中一些能够用来实现函数式编程的语言特性,并且通过许多实际的例子展示了函数组合、数据驱动编程和不可变数据结构的强大功能。所有代码示例均可用于.NET 6和C# 10。 主要内容 ● 高阶函数减少了代码的重复,可用更少的代码执行更多的操作 ● 基于纯函数的代码易于测试和优化 ● 编写高质量的API,准确描述程序的行为 ● 编写函数式风格的Web API ● 与LINQ的单组合
    目录
    第Ⅰ部分 入门 第1章 介绍函数式编程 3 1.1 什么是函数式编程 3 1.1.1 函数作为**类值 4 1.1.2 避免状态突变 4 1.1.3 编写具有**保证的程序 5 1.2 C#语言中的函数式编程 8 1.2.1 LINQ的函数式性质 8 1.2.2 函数式编码的简短语法 10 1.2.3 元组的语言支持 11 1.2.4 模式匹配和记录类型 13 1.3 将在本书中学到什么 16 1.4 本章小结 17 第2章 函数思维 19 2.1 什么是函数 19 2.1.1 映射函数 19 2.1.2 在C#中表示函数 20 2.2 高阶函数 24 2.2.1 依赖其他函数的函数 24 2.2.2 适配器函数 26 2.2.3 创建其他函数的函数 26 2.3 使用HOF避免重复 27 2.4 练习 30 2.5 本章小结 31 第3章 函数纯洁性很重要 33 3.1 什么是函数的纯洁性 33 3.1.1 纯洁性和副作用 34 3.1.2 管理副作用的策略 35 3.2 通过避免状态突变实现并行化 37 3.2.1 纯函数可良好地并行化 38 3.2.2 并行化不纯函数 39 3.2.3 避免状态突变 40 3.3 纯洁性和可测性 43 3.3.1 隔离I/O影响 43 3.3.2 实践:一个业务验证场景 44 3.3.3 为什么很难测试不纯函数 46 3.4 执行I/O的测试代码 47 3.4.1 面向对象的依赖注入 48 3.4.2 可测试性没有那么多样板 51 3.5 纯洁性和计算的发展 53 3.6 练习 54 3.7 本章小结 54 第Ⅱ部分 核心技术 第4章 设计函数签名和类型 57 4.1 设计函数签名 57 4.1.1 使用箭头符号编写签名 58 4.1.2 签名的信息量有多大 58 4.2 使用数据对象捕获数据 59 4.2.1 原始类型通常不够具体 60 4.2.2 使用自定义类型约束输入 61 4.2.3 编写“诚实的”函数 62 4.2.4 把值组合到复杂的数据对象中 64 4.3 使用Unit为数据缺失建模 65 4.3.1 为什么void不理想 65 4.3.2 弥合Action和Func之间的差异 67 4.4 本章小结 68 第5章 为数据可能缺失建模 69 5.1 每天都在使用糟糕的API 69 5.2 Option类型的介绍 71 5.3 实现Option 73 5.3.1 Option的理想实现 73 5.3.2 使用Option 73 5.3.3 创建None 74 5.3.4 创建Some 75 5.3.5 优化Option实现 76 5.4 Option作为偏函数的自然结果类型 78 5.4.1 解析字符串 78 5.4.2 在集合中查找数据 79 5.4.3 智能构造函数模式 80 5.5 处理null 81 5.5.1 为什么null是一个糟糕的想法 81 5.5.2 使用Option替代null来获得健壮性 82 5.5.3 不可空的引用类型 83 5.5.4 防止NullReference-Exception 85 5.6 练习 86 5.7 本章小结 87 第6章 函数式编程中的模式 89 6.1 将函数应用于结构的内部值 89 6.1.1 将函数映射到序列上 89 6.1.2 将函数映射到Option 90 6.1.3 Option是如何提高抽象级别的 93 6.1.4 函子 93 6.2 使用ForEach执行副作用 94 6.3 使用Bind链接函数 96 6.3.1 将返回Option的函数组合起来 97 6.3.2 使用Bind平铺嵌套列表 98 6.3.3 实际上,这被称为单子 100 6.3.4 Return函数 100 6.3.5 函子和单子之间的关系 101 6.4 使用Where过滤值 101 6.5 使用Bind组合Option和IEnumerable 102 6.6 在不同抽象级别上编码 104 6.6.1 常规值与**值 104 6.6.2 跨越抽象级别 105 6.6.3 重新审视Map与Bind 106 6.6.4 在正确的抽象级别上工作 107 6.7 练习 107 6.8 本章小结 108 第7章 使用函数组合设计程序 109 7.1 函数组合 109 7.1.1 复习函数组合 109 7.1.2 方法链 110 7.1.3 **界域中的组合 112 7.2 从数据流的角度进行思考 113 7.2.1 使用LINQ的可组合API 113 7.2.2 编写可组合性更好的函数 114 7.3 工作流编程 116 7.3.1 关于验证的一个简单工作流 116 7.3.2 以数据流的思想进行重构 117 7.3.3 组合带来了更大的灵活性 118 7.4 介绍函数式领域建模 119 7.5 端到端的服务器端工作流 120 7.5.1 表达式与语句 122 7.5.2 声明式与命令式 122 7.5.3 函数式分层 123 7.6 练习 124 7.7 本章小结 125 第Ⅲ部分 函数式设计 第8章 函数式错误处理 129 8.1 表示输出的更**方式 130 8.1.1 使用Either捕获错误细节 130 8.1.2 处理Either的核心函数 133 8.1.3 比较Option和Either 134 8.2 链接操作可能失败 135 8.3 验证:Either的一个**用例 137 8.3.1 为错误选择合适的表示法 137 8.3.2 定义一个基于Either的API 138 8.3.3 添加验证逻辑 139 8.4 将输出提供给客户端应用程序 140 8.4.1 公开一个类似Option的接口 141 8.4.2 公开一个类似Either的接口 142 8.4.3 返回一个DTO结果 143 8.5 Either的变体 144 8.5.1 在不同的错误表示之间进行更改 144 8.5.2 Either的特定版本 145 8.5.3 重构Validation和 Exceptional 146 8.5.4 保留异常 149 8.6 练习 150 8.7 本章小结 151 第9章 用函数构造应用程序 153 9.1 偏函数应用:逐个提供参数 153 9.1.1 手动启用偏函数应用 155 9.1.2 归纳偏函数应用 156 9.1.3 参数的顺序问题 157 9.2 克服方法解析的怪癖 158 9.3 柯里化函数:优化偏函数应用 160 9.4 创建一个友好的偏函数应用API 162 9.4.1 可文档化的类型 163 9.4.2 特殊化数据访问函数 164 9.5 应用程序的模块化及组合 166 9.5.1 OOP中的模块化 167 9.5.2 FP中的模块化 168 9.5.3 将函数映射到API端点 171 9.5.4 比较两种方法 173 9.6 将列表压缩为单个值 174 9.6.1 LINQ的Aggregate方法 174 9.6.2 聚合验证结果 176 9.6.3 收集验证错误 177 9.7 练习 178 9.8 本章小结 178 第10章 有效地处理多参函数 181 10.1 **界域中的函数应用程序 181 10.1.1 理解应用式 183 10.1.2 提升函数 185 10.1.3 基于属性的测试 186 10.2 函子、应用式、单子 188 10.3 单子定律 190 10.3.1 右恒等元 190 10.3.2 左恒等元 190 10.3.3 结合律 191 10.3.4 对多参函数使用Bind 193 10.4 通过对任何单子使用LINQ来提高可读性 193 10.4.1 对任意函子使用LINQ 194 10.4.2 对任意单子使用LINQ 195 10.4.3 let、where及其他LINQ子句 198 10.5 何时使用Bind或Apply 199 10.5.1 具有智能构造函数的验证 199 10.5.2 使用应用式流收集错误 201 10.5.3 使用单子流快速失败 202 10.6 练习 203 10.7 本章小结 203 第11章 表示状态和变化 205 11.1 状态突变的陷阱 205 11.2 理解状态、标识及变化 208 11.2.1 有些事物永远不变 209 11.2.2 表示非突变的变化 211 11.3 使用记录捕获域实体的状态 212 11.3.1 对记录初始化的细粒度控制 214 11.3.2 所有这些都是不可变的 216 11.4 数据与逻辑分离 218 11.5 本章小结 220 第12章 函数式数据结构简介 221 12.1 经典的函数链表 222 12.1.1 常见的列表操作 224 12.1.2 修改不可变列表 225 12.1.3 解构任何IEnumerable 227 12.2 二叉树 227 12.2.1 常见的树操作 228 12.2.2 结构共享 230 12.3 结论 231 12.4 练习 231 12.5 本章小结 232 第13章 事件溯源:持久化的函数式方法 233 13.1 关于数据存储的函数式思考 234 13.1.1 为什么数据存储只能追加 234 13.1.2 放松,并忘却存储状态 235 13.2 事件溯源的基础知识 236 13.2.1 表示事件 236 13.2.2 持久化事件 237 13.2.3 表示状态 238 13.2.4 表示状态转换 239 13.2.5 从过去的事件中重建当前状态 240 13.3 事件溯源系统的架构 241 13.3.1 处理命令 243 13.3.2 处理事件 245 13.3.3 添加验证 246 13.3.4 创建事件数据的视图 248 13.4 比较不同的不可变存储方法 251 13.4.1 Datomic与Event Store 252 13.4.2 领域是否受事件驱动 252 13.5 本章小结 253 第Ⅳ部分 **技术 第14章 惰性计算、延续以及单子组合之美 257 14.1 惰性的优点 258 14.1.1 用于处理Option的惰性API 258 14.1.2 组合惰性计算 261 14.2 使用Try进行异常处理 263 14.2.1 表示可能失败的计算 263 14.2.2 从JSON对象中**地提取信息 264 14.2.3 组合可能失败的计算 266 14.2.4 单子组合 267 14.3 为数据库访问创建中间件管道 268 14.3.1 组合执行安装/拆卸操作的函数 268 14.3.2 逃离厄运金字塔的秘方 269 14.3.3 捕获中间件函数的本质 270 14.3.4 实现中间件的查询模式 272 14.3.5 添加计时操作的中间件 274 14.3.6 添加管理数据库事务的中间件 275 14.4 本章小结 277 第15章 有状态的程序和计算 279 15.1 管理状态的程序 280 15.1.1 将数据缓存到内存中 281 15.1.2 重构以实现可测试性和错误处理 283 15.1.3 有状态的计算 285 15.2 一种用于生成随机数据的语言 285 15.2.1 生成随机整数 286 15.2.2 生成其他基元 287 15.2.3 生成复杂的结构 288 15.3 有状态计算的通用模式 290 15.4 本章小结 293 第16章 使用异步计算 295 16.1 异步计算 295 16.1.1 对异步的需求 296 16.1.2 用Task表示异步操作 297 16.1.3 一个Task即为一个将来值的容器 298 16.1.4 处理失败 300 16.1.5 一个用于货币转换的HTTP API 302 16.1.6 如果失败,请再试几次 303 16.1.7 并行运行异步操作 304 16.2 异步流 306 16.2.1 以异步流的方式读取文件 307 16.2.2 以函数方式使用异步流 308 16.2.3 从多个流中消费数据 309 16.2.4 使用异步流进行聚合和排序 309 16.3 本章小结 310 第17章 遍历和堆叠的单子 311 17.1 遍历:处理**值列表 311 17.1.1 使用单子的Traverse验证值列表 313 17.1.2 使用应用式Traverse收集验证错误 314 17.1.3 将多个验证器应用于单个值 316 17.1.4 组合使用Traverse与Task以等待多个结果 317 17.1.5 为单值结构定义Traverse 319 17.2 组合异步和验证(或其他任何两个单子效果) 320 17.2.1 堆叠单子的问题 320 17.2.2 减少结果的数量 322 17.2.3 具有一个单子堆叠的LINQ表达式 323 17.3 本章小结 325 第18章 数据流和Reactive Extensions 327 18.1 用IObservable表示数据流 328 18.1.1 时间上的一个值序列 328 18.1.2 订阅IObservable 329 18.2 创建IObservable 331 18.2.1 创建定时器 331 18.2.2 使用Subject告知IObservable应何时发出信号 332 18.2.3 从基于回调的订阅中创建IObservable 333 18.2.4 由更简单的结构创建IObservable 334 18.3 转换和组合数据流 335 18.3.1 流的转换 335 18.3.2 组合和划分流 337 18.3.3 使用IObservable进行错误处理 339 18.3.4 融会贯通 340 18.4 实现贯穿多个事件的逻辑 341 18.4.1 检测按键顺序 342 18.4.2 对事件源做出反应 344 18.4.3 通知账户何时透支 346 18.5 应该何时使用IObservable 348 18.6 本章小结 349 第19章 并发消息传递 351 19.1 对共享可变状态的需要 351 19.2 理解并发消息传递 353 19.2.1 在C#中实现代理 355 19.2.2 开始使用代理 356 19.2.3 使用代理处理并发 请求 357 19.2.4 代理与角色 361 19.3 “函数式API”与“基于代理的实现” 362 19.3.1 代理作为实现细节 362 19.3.2 将代理隐藏于常规API的背后 364 19.4 LOB应用程序中的并发消息传递 364 19.4.1 使用代理来同步访问账户数据 365 19.4.2 保管账户的注册表 366 19.4.3 代理不是对象 368 19.4.4 融会贯通 370 19.5 本章小结 371 附录A 使用C#的旧版本 373 A.1 C#9之前的不可变数据对象 373 A.1.1 约定不变性 373 A.1.2 定义复制方法 374 A.1.3 强制不变性 375 A.1.4 一直不变 376 A.1.5 复制方法没有样板 377 A.1.6 不变性策略的比较 379 A.2 C# 8之前的模式匹配 379 A.2.1 C#对模式匹配的增量支持 380 A.2.2 模式匹配表达式的自定义解决方案 381 A.3 再次讨论事件溯源的示例 382 A.4 结论 384 结束语 385

    与描述相符

    100

    北京 天津 河北 山西 内蒙古 辽宁 吉林 黑龙江 上海 江苏 浙江 安徽 福建 江西 山东 河南 湖北 湖南 广东 广西 海南 重庆 四川 贵州 云南 西藏 陕西 甘肃 青海 宁夏 新疆 台湾 香港 澳门 海外