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 接口的类,要求创建对象的时候传入一个用于恢复的函数。这种方式既然常用,写一个这样的类也不错。








原文地址:https://www.cnblogs.com/greatim/p/3992313.html