• F# 的血继限界(2)


           某年某月,曾经某人希望 C# 出现 Java 匿名类的类似特性,然而最终他被 Java 的匿名类恶心到了。所谓的 Java 匿名类特性,即可以在项目里动态地创建一个类型,它继承了一个现有类,或者实现了一个现有接口。详情见《匿名类型的硬伤:围绕this的成员捕获策略

            很庆幸 F# 有“对象表达式”。它很优雅地实现了这个特性,而且不带副作用。对象表达式的好处,不仅仅在于,它避免了为处理特定情况而创建太多类型,同时因为它是内联的,因此它享受了闭包的好处,把函数式发挥到了极致。以下例子是个常用的手段,它巧妙的结合了对象表达式和 use/using 关键字。这个例子表达了一种需求:它临时改变环境之后,必须自动恢复原状,也可以扩展到更多应用。

    open System

     

    let changeColor clr =

        let orig = Console.ForegroundColor

        Console.ForegroundColor <- clr

     

        // 用对象表达式返回一个实现了 IDisposable 接口的对象

        { new IDisposable with

            member x.Dispose () =

                Console.ForegroundColor <- orig

        }

        

     

    [<EntryPoint>]

    let main argv =

        Console.WriteLine "原来的颜色"

        do  use clr = changeColor ConsoleColor.Red

            Console.WriteLine "变成红色"

        Console.WriteLine "好贱,又变回来了"

        Console.ReadLine () |> ignore

        0

     


    C# 里没有对象表达式,也没有其他“利用闭包动态实现子类的可用方式。但是类似这个例子,C# 也可以通过一些函数式方法来实现。

    1、可以 在 
    changeColor 函数里设定一个函数参数,让改变颜色后的操作写在一个函数里传入 changeColor。changeColor 在调用函数操作后再恢复原状。不过,这是另一种架构。我们不说某一种架构就比另一种架构好,但是能够按实际需求,灵活应用才是最好的。

    2、写一个实现 
    IDisposable 接口的类,要求创建对象的时候传入一个用于恢复的函数。这种方式既然常用,写一个这样的类也不错。








  • 相关阅读:
    LeetCode第[84]题(Java):Largest Rectangle in Histogram(最大的矩形柱状图)
    LeetCode第[79]题(Java):Word Search(矩阵单词搜索)
    LeetCode第[78]题(Java):Subsets(求子集)扩展——第[90]题:Subsets 2
    关于SpringMVC中两种映射器不能共存的解决
    LeetCode第[73]题(Java):Set Matrix Zeroes(矩阵置0)
    php分页的实现
    PHP编码规范
    PHP常用函数
    PHP配置文件详解php.ini
    面向对象编程——parent—this
  • 原文地址:https://www.cnblogs.com/greatim/p/3992313.html
Copyright © 2020-2023  润新知