内容简介:C# 有個著名的macOS High Sierra 10.13.6.NET Core 2.1
C# 有個著名的 using
statement,對於實踐 IDisposable
的物件特別好用,但 using
是個 statement,在 Imperative 世界沒問題,但在 Functional 世界,statement 就類似 句點
,讓我們無法繼續 Pipeline 或對其他 function 做 Compose,我們能否比照將 foreach
statement 重構成 ForEach()
function,也將 using
statement 重構成 using()
function 呢 ?
Version
macOS High Sierra 10.13.6
.NET Core 2.1
C# 7.2
F# 4.5
Rider 2018.1.4
C# 之 Using Statement
using System; using System.IO; namespace ConsoleApp { public static class Program { public static void Main() { using (var streamReader = new StreamReader("TestFile.txt")) { var line = streamReader.ReadToEnd(); Console.WriteLine(line); // Hello World } } } }
StreamReader
是個典型實踐 IDisposable
的物件,所以在使用時都會使用 using statement
包起來,等離開 {}
scope 時,自動呼叫 Dispose()
釋放 resource。
這些都是我們都習慣的 C#。
但 using
是 statement,在 Imperative 世界沒問題,反正程式碼都是一行一行循序執行。
但在 Functional 世界,我們要求 code 要 Pipeline,要 Compose,所以 FP 喜歡使用 expression,不喜歡 statement。
Statemet 就類似 句點
,讓所有的 Pipeline 都中斷了。
其實仔細看 using
statement,其實包含幾個部分:
- Setup : 獲得 resource
- Body : 執行 resource
- Teardown : 釋放 resource
其中 using
statement 就是幫我們做 teardown 部分。
因此我們可以自己寫一個 Using()
function,將 setup 與 body 傳入 Using()
。
C# 之 Using() Function
using System.IO; using static Functional.F; namespace ConsoleApp { public static class Program { public static void Main() { Using(new StreamReader("TestFile.txt"), ReadFile) .WriteLine(); string ReadFile(StreamReader streamReader) => streamReader.ReadToEnd(); } } }
10 行
Using(new StreamReader("TestFile.txt"), ReadFile) .WriteLine();
使用 Using()
function,將 setup 傳入第一個參數,將 body 傳入第二個參數。
由於 ReadFile()
回傳為 string
,因此 Using()
也是回傳 string
,這樣就可以使用 Pipeline 方式 WriteLine()
直接印出。
13 行
string ReadFile(StreamReader streamReader) => streamReader.ReadToEnd();
Body 以 local function 定義。
至於 Using()
與 WriteLine()
怎麼來的呢 ? 是我們自己寫的 Higher Order Function。
using System; namespace Functional { public static class F { public static R Using<TDisp, R>(TDisp disposable, Func<TDisp, R> f) where TDisp : IDisposable { using (disposable) return f(disposable); } public static void WriteLine(this string data) { Console.WriteLine(data); } } }
第 7 行
public static R Using<TDisp, R>(TDisp disposable, Func<TDisp, R> f) where TDisp : IDisposable { using (disposable) return f(disposable); }
自己寫一個 Using()
HOF,第一個參數傳入 IDisposable
物件,第二個參數傳入 body function。
12 行
public static void WriteLine(this string data) { Console.WriteLine(data); }
自己為 string
加上 WriteLine()
Extension Method,這就就可以對 string
繼續 Pipeline 印出。
C# 為了讓 using
用起來更 FP,我們必須自己實作 Using()
與 WriteLine()
,但在 Functional First 的 F#,除了提供 Imperative 的 use
外,也提供了 Functional 的 using()
,我們完全不用自己另外實作
F# 之 Use Bind
open System.IO let readFromFile (fileName: string) = use streamReader = new StreamReader(fileName) streamReader.ReadToEnd() readFromFile "TestFile.txt" |> printf "%A"
F# 之 use
類似於 let
,差別是 use
在離開 function 就會呼叫 Dispose()
,不需特別加上 {}
縮排一層。
由於 readFromFile()
回傳 string
,可以直接 Pipeline 接內建的 printf()
。
但 use
仍然是個 statement。
F# 之 Using() Function
open System.IO let readFile (streamReader: StreamReader) = streamReader.ReadToEnd() let readFromFile (fileName: string) = using(new StreamReader(fileName)) readFile readFromFile "TestFile.txt" |> printf "%A"
第 6 行
let readFromFile (fileName: string) = using(new StreamReader(fileName)) readFile
改用 F# 內建的 using()
,第一個參數傳入 IDisposable
物件,第二個參數傳入 body function,其實跟自己用 C# 實作的 Using()
是一樣的。
第 3 行
let readFile (streamReader: StreamReader) = streamReader.ReadToEnd()
定義 body function。
由於 using()
與 printf()
都是 F# 內建,因此我們就不必再自己實作了
Conclusion
-
將 C# 由
using
statement 改成using()
function,乍看之下意義不大;但若去看 F# 同時提供use
statement 與using()
function 時,就可看出 F# 的用心良苦,同時支援了 Imperative 與 Functional 兩種 paradigm -
由於 F# 每個 function 都是 composable,因此我們就不必再自已寫
WriteLine()
了,直接printf()
就可以 pipeline 起來
Sample Code
Reference
Enrico Buonanno, Functional Programming in C#
以上所述就是小编给大家介绍的《將 Using Statement 重構成 Using() Function》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
现代操作系统(原书第4版)
[荷] Andrew S. Tanenbaum、[荷] Herbert Bos / 陈向群、马洪兵 等 / 机械工业出版社 / 2017-7 / 89.00
Andrew S. Tanenbaum教授编写的教材《现代操作系统》现在已经是第4版了。第4版在保持原有特色的基础上,又增添了许多新的内容,反映了当代操作系统的发展与动向,并不断地与时俱进。 对比第3版,第4版有很多变化。一些是教材中多处可见的细微变化,一些是就某一功能或机制增加了对最新技术的介绍,如增加了futex同步原语、读–复制–更新(Read-Copy-Update)机制以及6级RA......一起来看看 《现代操作系统(原书第4版)》 这本书的介绍吧!