[<AutoOpen>] 有反义词吗?
Is there an inverse to [<AutoOpen>]?
这个 post 包含两个相互关联的问题,它们具有清理资源的共同点。我已经阅读了这个 SO post,以及 Microsoft 站点上的其他几个试图确定什么是托管资源与非托管资源的文档。根据我阅读的内容,以下代码块使用 .Net 托管资源。这来自非 DLL F# 库。
namespace Toa.csv_lib
open System
open System.Threading
open System.Collections.Generic
open System.Linq
open System.Text
open System.Threading.Tasks
open System.IO
open Microsoft.VisualBasic.FileIO
[<AutoOpen>]
module csv_lib =
let initCsvLib fn delim =
let csvFileH = new TextFieldParser(fn:string)
csvFileH.TextFieldType = FieldType.Delimited |> ignore
csvFileH.SetDelimiters(delim) |> ignore
csvFileH
let readCsvLibLine csvFileH =
(csvFileH:TextFieldParser).ReadFields()
let retCsvData csvFileH =
let csvData = new List<string[]>()
if not (csvFileH:TextFieldParser).EndOfData then
let column_headings = readCsvLibLine csvFileH
csvData.Add(column_headings) |> ignore
let read_rest_of_csv() =
csvData.Add(readCsvLibLine csvFileH) |> ignore
not (csvFileH:TextFieldParser).EndOfData
while read_rest_of_csv() do ignore None
csvData // Last expression is returned.
尽管我相信 csvFileH
和 csvData
是托管资源,但我想知道是否存在与 [<AutoOpen>]
相反的资源,是否需要一个?这将是一个允许库释放在 [<AutoOpen>]
.
中创建的所有资源的指令
我可以重组此代码,使 using
围绕 csvFileH
,因为只需要读取 .csv 文件的句柄。但是鉴于返回了 List<string[]> csvData
类型,它仍然被认为是一种托管资源,当应用程序关闭时将被垃圾处理。
[<AutoOpen>]
所做的只是在没有 open
语句的情况下公开模块的内容。而已。它不是 运行 任何代码,它只是自动公开一些需要手动公开的内容。
在你的例子中,当你引用这个模块时,你实际上并没有执行任何事情。 initCsvLib
是一个带有两个参数的纯函数,returns 是 csvFileH
的一个实例。这里没有初始化代码运行。例如,如果你有
module Foo =
let expensiveThing = ExpensiveThing()
let myFn arg1 arg2 =
// This isn't run until the function myFn is called.
let expensiveThing = ExpensiveThing()
// ...
那你可能手头有问题。在那种情况下,尽管您必须记住模块实际上是静态的 类 并且基本上遵循与 C# 中的静态 类 相同的规则(考虑静态构造函数何时是 运行)和从那里开始。
但是如果你到了那个地步,你应该问问自己为什么首先要在构造函数中进行如此昂贵的操作...
这个 post 包含两个相互关联的问题,它们具有清理资源的共同点。我已经阅读了这个 SO post,以及 Microsoft 站点上的其他几个试图确定什么是托管资源与非托管资源的文档。根据我阅读的内容,以下代码块使用 .Net 托管资源。这来自非 DLL F# 库。
namespace Toa.csv_lib
open System
open System.Threading
open System.Collections.Generic
open System.Linq
open System.Text
open System.Threading.Tasks
open System.IO
open Microsoft.VisualBasic.FileIO
[<AutoOpen>]
module csv_lib =
let initCsvLib fn delim =
let csvFileH = new TextFieldParser(fn:string)
csvFileH.TextFieldType = FieldType.Delimited |> ignore
csvFileH.SetDelimiters(delim) |> ignore
csvFileH
let readCsvLibLine csvFileH =
(csvFileH:TextFieldParser).ReadFields()
let retCsvData csvFileH =
let csvData = new List<string[]>()
if not (csvFileH:TextFieldParser).EndOfData then
let column_headings = readCsvLibLine csvFileH
csvData.Add(column_headings) |> ignore
let read_rest_of_csv() =
csvData.Add(readCsvLibLine csvFileH) |> ignore
not (csvFileH:TextFieldParser).EndOfData
while read_rest_of_csv() do ignore None
csvData // Last expression is returned.
尽管我相信 csvFileH
和 csvData
是托管资源,但我想知道是否存在与 [<AutoOpen>]
相反的资源,是否需要一个?这将是一个允许库释放在 [<AutoOpen>]
.
我可以重组此代码,使 using
围绕 csvFileH
,因为只需要读取 .csv 文件的句柄。但是鉴于返回了 List<string[]> csvData
类型,它仍然被认为是一种托管资源,当应用程序关闭时将被垃圾处理。
[<AutoOpen>]
所做的只是在没有 open
语句的情况下公开模块的内容。而已。它不是 运行 任何代码,它只是自动公开一些需要手动公开的内容。
在你的例子中,当你引用这个模块时,你实际上并没有执行任何事情。 initCsvLib
是一个带有两个参数的纯函数,returns 是 csvFileH
的一个实例。这里没有初始化代码运行。例如,如果你有
module Foo =
let expensiveThing = ExpensiveThing()
let myFn arg1 arg2 =
// This isn't run until the function myFn is called.
let expensiveThing = ExpensiveThing()
// ...
那你可能手头有问题。在那种情况下,尽管您必须记住模块实际上是静态的 类 并且基本上遵循与 C# 中的静态 类 相同的规则(考虑静态构造函数何时是 运行)和从那里开始。
但是如果你到了那个地步,你应该问问自己为什么首先要在构造函数中进行如此昂贵的操作...