Destructors in C#

Ok, this may be a dumb question, but I'm looking for anything that resembles a C++ destructor in C#.

I know that the garbage collector is used to free up resources, etc.  However, destructors can be quite useful for much more than deleting memory or freeing up handles, etc.

Many times (in C++) I will use destructors to trigger events when an object goes out of scope.  I actually use some objects just for their destructor.  I want to have that capability in C#.  Is it possible?  I don't care how I get there, as long as I can reliably run some chunk of code based on the event of an object going out of scope.

Any help is appreciated!

Douglas Holt
douglasholt@cox.net
DouglasHoltAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Timbo87Commented:
Destructors are possible in C#, although they can't be explicitly called (I believe they can be in C++, but I don't do much development in it). They are syntacticly identical to C++.

public class A
{
     ~A()
     {
          Console.WriteLine("Running the A destructor.");
     }
}

Under the hood, this is translated to override the Finalize method of the base class Object.

There's an in-depth article which goes into some of the IL here:
http://www.c-sharpcorner.com/Code/2002/June/UnderstandingDestructors.asp
0
DouglasHoltAuthor Commented:
I understand roughly how the Garbage Collector works.  And I know that destructors are called by the GC.  What I need is something that is reliably called upon the event of an object falling out of scope.

One thought is this:  An object's ref count drops to zero when it falls out of scope.  Is there an event or other mechanism that can be tapped into when the ref count drops to zero?

Remember, I'm not using this like a destructor to free up resources, I need it for timing, synchronization, etc.  So it has to happen just like a C++ destructor.  I don't care what this mechanism is called, or how it's used, and I know it must exist or the Ref Count could never drop to zero.
0
Arnold_VoslooCommented:
There is more to this question than meets the eye.

First of all, the only methods that are automatically called when an object falls out of scope is either the destructor or the Finalize() method if it is specified.  These however can't be completely relied upon because they are only called when the GC does a pass.  And then it is not even guaranteed!

What you can do is to implement the IDisposable interface, and use the Dispose() Method to call anything that you want.  This method must however be called explicitly.

In this Dispose() method, you must call the GC.SuppressFinalize() Method to stop the object from being finalized, because when an object falls out of scope it is put on the finalization que, and this que still has a reference to the object, which defeats the purpose in this case.

What you can do then, is to manually count the references to the object in the Dispose() method, and when the count == 0 you have your required state.

You can also still add a destructor or a Finalize() method to destroy the object if it is not done explicitly by a user of your class.

public YourClass : IDisposable {
   ~YourClass() {
      //Put your destructor code here
   }

   public void Dispose() {
      Dispose(true);
   }

   protected void Dispose(bool disposing) {
      if (disposing) {
         GC.SuppressFinalize(this);
         //Dispose of your managed objects if disposing
      }
      //Dispose of your external resources here
      ...
   }
   ...
}

I hope this makes any sense
0
Cloud Class® Course: Microsoft Windows 7 Basic

This introductory course to Windows 7 environment will teach you about working with the Windows operating system. You will learn about basic functions including start menu; the desktop; managing files, folders, and libraries.

DouglasHoltAuthor Commented:
But the whole point is to eliminate the need to explicitly call something like Dispose.  So, this completely defeats my purpose.
0
Arnold_VoslooCommented:
Well, like I said: the only methods that are called automatically are the destructor or the Finalize() method, but then you have to rely on the GC to delete the reference.  And you can't use this for timing or synchronization, as you can't be sure when the GC is going to delete it.
0
DouglasHoltAuthor Commented:
So, the bottom line is that C# is not able to do what C++ destructors do, no matter what, period, end of story?
0
Arnold_VoslooCommented:
I wouldn't go so far as to say that it is impossible.  It's just highly unlikely that it would work the same way because of the GC.  In C++, you deleted the objects yourself, so it would go out of scope immediately.  In C# you have to wait for the GC.

You can call the GC explicitly to schedule a GC pass, but you still can't be sure that it will delete the required object.

I am not 100% sure what you are allowed to do with unmanaged code in C#, but you might want to look into that and see if you can then make it happen exactly as in C++.
0
DouglasHoltAuthor Commented:
I have to stay with managed code for my client.

By calling the GC to make a pass, that would be as much work if not more than calling an explicit Dispose, or Close method.

The solution I'm looking for cannot be related to the GC.  I know what the GC does, and that's not what I'm after.  I'm after the event that must get called to decrement the object's ref count immediately as it goes out of scope.  But I'm betting that it's not an "event" that can be tapped into.  My guess is that it's hardwired in the generated code, and nothing can access it.  But I'm all ears if there is any other potential solution!!!
0
msdixonCommented:
another way is implementing the IDisposable interface, and then use a using block.

using (myClass cls = new myClass()) {
    // set properties, call methods, etc.
    // at the end of the using block dispose is automatically called.
}

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
DouglasHoltAuthor Commented:
You are an absolute genius!  Yes, this is exactly what I want.  It's not nearly as pretty as C++, but it does work.  I set breakpoints, and it hits them just exactly as I hoped!  Thank you, thank you, thank you!!!  Yes, you get the points!
0
DouglasHoltAuthor Commented:
msdixon,

Excellent, now I just have one more piece to my puzzle.  Could I get you to take a look at my other question: "How can I store a ref of an object within a class for later use?" in this section?  Here's the link:

http://www.experts-exchange.com/Programming/Programming_Languages/C_Sharp/Q_21207416.html

You have no idea how happy this makes me.  I've been cursing C#'s lack of destructors since I first was forced to use it over C++.  I'll be dancing today!
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C#

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.