tags:

views:

151

answers:

5

I have digging through the C# code generated by SWIG for Quantlib and came across the following code that gave me a humbling moment.

Each of the generated classes implement IDisposable, and each of the generated classes have this convention pointed out below.

public class MultiPath : IDisposable { // MultiPath is interchangable
  private HandleRef swigCPtr;
  protected bool swigCMemOwn;

  internal MultiPath(IntPtr cPtr, bool cMemoryOwn) {
    swigCMemOwn = cMemoryOwn;
    swigCPtr = new HandleRef(this, cPtr);
  }

  internal static HandleRef getCPtr(MultiPath obj) {
    return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr;
  }

  ~MultiPath() { // <---- 
    Dispose();
  }

  public virtual void Dispose() {
    lock(this) {
      if (swigCPtr.Handle != IntPtr.Zero) {
        if (swigCMemOwn) {
          swigCMemOwn = false;
          NQuantLibcPINVOKE.delete_MultiPath(swigCPtr);
        }
        swigCPtr = new HandleRef(null, IntPtr.Zero);
      }
      GC.SuppressFinalize(this);
    }
  }
  // snip
}

If I'm reading this correctly, the bitwise complement operator is applied to the constructor of the class, so my questions are

  1. Why is the purpose of ~ operator in this example?
  2. What effect does it have?
  3. What are the correct situations to use such an operator and technique?

Edit:

Just for clarity, the ~ is this case is called a Destructor. Thanks's @Arcturus.

+8  A: 

Its the destructor!

In simple terms a destructor is a member that implements the actions required to destruct an instance of a class. The destructors enable the runtime system, to recover the heap space, to terminate file I/O that is associated with the removed class instance, or to perform both operations.

Arcturus
May be destructor?
Eugene Cheverda
As usual, as soon as I posted I found http://www.codeproject.com/KB/cs/destructorsincs.aspx and http://msdn.microsoft.com/en-us/library/66x5fx1b(VS.80).aspx
Ahmad
Hehe.. I blame my foreignness ;)
Arcturus
I quite liked deconstructor. :)
Chris
Yeah, its kinda the opposite of the constructor.. so de-constructor it ;)
Arcturus
Isn't it actually called the finalizer in c#? because it isn't really a destructor
Sekhat
@Sekhat - The `~` operator is the Destructor which does in fact boil down to a try-catch block with a call to the `Finalize` method.
Ahmad
A deconstructor would be a piece of code that performed a Derridean analysis of the social meaning of the class ;) Joking aside, I prefer to call them "finalisers", because "destructor" often leads to people carrying mental baggage over from C++ that doesn't really correlate (Managed C++ has both finalisers and destructors, and it's the former the corresponds to the C# code above).
Jon Hanna
That article is very poorly written and quite misleading. For example, it says that it allows the runtime to recover heap space. This isn't true at all. Managed heap space is handled by the GC without this method. Unmanaged heap space is recovered by `Marshal.FreeXXX`. The GC may happen to call the destructor, which may happen to free unmanaged memory, or not.
Jonathan Allen
@jonathan - are you referring to the codeproject article?
Ahmad
@Ahmad - No, the one on C# Corner. I like the Code Project article.
Jonathan Allen
+1  A: 

It marks the destructor of the class. Follow Destructors (C# Programming Guide) for more info.

Eugene Cheverda
+1  A: 

It signifies a destructor:

Destructors are used to destruct instances of classes.

They are not used much in C# as managed resources are taken care of by the garbage collector.

Oded
Can the downvote please explain?
Oded
Perfectly legit - i think the downvoter missed the 'managed resources' part
Ahmad
The garbage collector only takes care of managed memory. When teaching people about this topic, it is very important to stress that no other resources are handled by the garbage collector.
Jonathan Allen
+1  A: 

that's a distructor - at least in C++, and looks like C# decided to have it unlike java that does not have it

kartheek
C# and Java both have finalizers, neither one has a destructor.
Ben Voigt
+2  A: 

It is short-hand for "Finalize", a non-public method that might get called by the garbage collector if you forget to call Dispose yourself.

I stress the word 'might'. Unless you do stupid things like call GC.WaitForPendingFinalizers, .NET doesn't promise you that it will actually clean up your unmanaged resoueces like pointers and database connections. This is just an extra layer of protection in case your code is screwed up.

Note the line GC.SuppressFinalize(this);. This tells the garbage collector that you remembered to call Dispose and it doesn't need to waste time running the Finalize method.

Jonathan Allen
@jonathan - are you saying that if I use an instance of the above class, I should call the Dispose method to ensure that resources are cleaned up and not fully rely on the GC to do it for me.
Ahmad
Exactly. The only thing you can trust the GC to clean up is managed memory. Everything else is still your responsibility.
Jonathan Allen
@jonathan - would this also unload the native dependant dll such there will be no OS hooks/handles attached to it?
Ahmad
If you create and delete objects in a loop, would you want to waste time constantly loading and unloading the dll? Probably not, so I doubt you that you can unload dlls this way.
Jonathan Allen