2

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.

Community
  • 1
  • 1
Ahmad
  • 22,657
  • 9
  • 52
  • 84
  • 1
    The patterns in this code don't look right; for instance, the `IDisposable` pattern should be made in a different way since the class isn't sealed, and this class should use or inherit from `SafeHandle` to perform its "unmanaged handle" work. – Lucero Oct 04 '10 at 08:05
  • @lucerro - the code above was automatically generated by SWIG - so I can't really comment. All of this is still new to me. – Ahmad Oct 04 '10 at 08:24
  • @lucero - isn't `SafeHandle` more applicable to OS related tasks based on this article (http://msdn.microsoft.com/en-us/library/fh21e17c.aspx)? – Ahmad Oct 04 '10 at 08:43
  • basically its an abstract base class for all sorts of unmanaged handles which *must* be released when an AppDomain is unloaded. This may or may not be necessary in this case; normal finalizers ("destructors") don't run in all cases. See also http://www.bluebytesoftware.com/blog/2005.12.27.NeverWriteAFinalizerAgainWellAlmostNever.aspx – Lucero Oct 04 '10 at 10:02

5 Answers5

8

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.

Murph
  • 9,985
  • 2
  • 26
  • 41
Arcturus
  • 26,677
  • 10
  • 92
  • 107
  • 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 Oct 04 '10 at 07:49
  • Hehe.. I blame my foreignness ;) – Arcturus Oct 04 '10 at 07:50
  • I quite liked deconstructor. :) – Chris Oct 04 '10 at 08:26
  • Yeah, its kinda the opposite of the constructor.. so de-constructor it ;) – Arcturus Oct 04 '10 at 08:31
  • 1
    Isn't it actually called the finalizer in c#? because it isn't really a destructor – Sekhat Oct 04 '10 at 08:41
  • @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 Oct 04 '10 at 09:13
  • 3
    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 Oct 04 '10 at 09:31
  • 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 Oct 05 '10 at 02:21
  • @Ahmad - No, the one on C# Corner. I like the Code Project article. – Jonathan Allen Oct 06 '10 at 22:13
2

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
  • 68,373
  • 70
  • 259
  • 447
  • 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 Oct 04 '10 at 08:38
  • Exactly. The only thing you can trust the GC to clean up is managed memory. Everything else is still your responsibility. – Jonathan Allen Oct 05 '10 at 02:12
  • would this also unload the native dependant dll such there will be no OS hooks/handles attached to it? – Ahmad Oct 07 '10 at 12:13
  • 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 Oct 07 '10 at 16:47
1

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

Eugene Cheverda
  • 8,760
  • 2
  • 33
  • 18
1

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
  • 489,969
  • 99
  • 883
  • 1,009
  • Perfectly legit - i think the downvoter missed the 'managed resources' part – Ahmad Oct 04 '10 at 08:39
  • 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 Oct 05 '10 at 02:15
1

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

kartheek
  • 763
  • 3
  • 7