内容简介: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》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
About Face 3
Alan Cooper、Robert Reimann、David Cronin / John Wiley & Sons / 2007-5-15 / GBP 28.99
* The return of the authoritative bestseller includes all new content relevant to the popularization of how About Face maintains its relevance to new Web technologies such as AJAX and mobile platforms......一起来看看 《About Face 3》 这本书的介绍吧!