F# Equivalent of Destructor
Asked Answered
G

3

18

I am translating a C# class that wraps an unmanaged library to F#. I have run into the seemingly simple problem of rewriting the destructor that follows.

class Wrapper {

    // P/Invoke ellided

    private SomeType x;

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

    public ~Wrapper() {
        End();
    }

The simplified F# code I have at this point is as follows:

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()

How can I modify this F# code to have the same behaviour? My search for F# destructor turned up no results in the books I have or on the web.

Thank you.

Gabo answered 15/4, 2011 at 12:34 Comment(8)
Are you trying to implement IDisposable interface in your class that aggregates unmanaged resources?Heterotopia
You have a C# class that has a finalizer but doesn't implement IDisposable? How bizarreBlacksmith
FYI - here's a blog article on how to implement IDisposable properly: atalasoft.com/cs/blogs/stevehawley/archive/2006/09/21/…Asben
Implementing IDisposable in a thread-safe way may be harder.Heterotopia
I am learning F# and improving my C# as I make this translation of another persons code. Thank you for the advice on using IDisposable, I have much room to improve and would like to make positive contributions to this code.Gabo
As a rule of thumb, you need to implement IDisposable if you aggregate a disposable object, or if you hold on to an unmanaged resource. Cleanup is done differently for these two scenarios. Otherwise, keep it simple, don't litter your code with dotnetisms.Heterotopia
@Heterotopia : Wow, that was an excellent way of wording it.Blacksmith
@Blacksmith : I heard it in school, in a class taught by Venkat Subramaniam.Heterotopia
H
25

Have you tried looking for F# finalizer?

override x.Finalize() = ...
Heterotopia answered 15/4, 2011 at 12:39 Comment(0)
L
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# Class Library Template

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

Lamellibranch answered 4/2, 2012 at 15:38 Comment(0)
D
0

I think it must be defined the same as C# compiler does

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

Because exception in your finalization code can corrupt something. Otherwise I misunderstand why C# does that.

Divulgence answered 15/4, 2022 at 18:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.