F#的析构函数等价物

17

我正在将一个包装非托管库的C#类翻译为F#。我遇到了一个看似简单的问题,需要重新编写紧随其后的析构函数。

class Wrapper {

    // P/Invoke ellided

    private SomeType x;

    public Wrapper() {
        x = new SomeType();
        Begin();
    }

    public ~Wrapper() {
        End();
    }

我目前拥有的简化版 F# 代码如下:

type Wrapper() =
  [<Literal>]
  static let wrappedDll = "Library.dll"

  [<DllImport(wrappedDll , EntryPoint = "Begin")>]
  static extern void Begin()

  [<DllImport(wrappedDll , EntryPoint = "End")>]
  static extern void End()

  let x = new SomeType()

  do
    Begin()

我该如何修改这段 F# 代码,使其具有相同的行为?我搜索了我手头的书籍和网络上的 F# 析构函数,但都没有结果。

谢谢。


2
你有一个带有终结器但没有实现 IDisposable 接口的 C# 类?多么奇怪。 - ildjarn
1
请注意 - 这是一篇关于如何正确实现IDisposable的博客文章:http://www.atalasoft.com/cs/blogs/stevehawley/archive/2006/09/21/10887.aspx - plinth
2
作为一个经验法则,如果你聚合了一个可释放对象或者持有一个非托管资源,你需要实现IDisposable接口。这两种情况下的清理方式是不同的。否则,保持简单,不要在代码中滥用dotnetisms。 - GregC
1
@GregC:哇,那真是一种非常优秀的表达方式。 - ildjarn
1
@ildjarn:我在学校里听到的,是由Venkat Subramaniam教授的课程。 - GregC
显示剩余3条评论
3个回答

25

你尝试过寻找 F# 的终结器吗?

override x.Finalize() = ...

12
namespace FSharp.Library  

type MyClass() as self = 

    let mutable disposed = false;

    // TODO define your variables including disposable objects

    do // TODO perform initialization code
        ()

    // internal method to cleanup resources
    let cleanup(disposing:bool) = 
        if not disposed then
            disposed <- true

            if disposing then
                // TODO dispose of managed resources
                ()

            // TODO cleanup unmanaged resources
            ()

    // implementation of IDisposable
    interface IDisposable with
        member self.Dispose() =
            cleanup(true)
            GC.SuppressFinalize(self)

    // override of finalizer
    override self.Finalize() = 
        cleanup(false)

F#类库模板

http://blogs.msdn.com/b/mcsuksoldev/archive/2011/06/05/f-class-library-template.aspx


0

我认为它必须与C#编译器定义相同

override c.Finalize() =
    try
        // do finalization
    finally
        base.Finalize()

因为在你的终结代码中出现异常可能会破坏某些东西。 否则我不理解为什么C#要这样做。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接