Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proper use of destructor c#

So I have been looking into implementing a destructor for a class I have written and I'm not sure how to really free up the memory or if this will be handled by garbage collection.

class AutomatedTest
{
   public bool testComplete = false;
   public bool testStopRequest = false;

   public List<Command> commandList = new List<Command>();

   private bool loggingEnabled = false;
   ...


   public AutomatedTest(TestList testToCreate)
   {
       // Create a list of Command objects and add them to the list
   }
}  

How the class is used:

for(int numTests = 0; numTests < 20; numTests++)
{
    AutomatedTest test1 = new AutomatedTest(TestList._1DayTest);
    RunAutoTest(test1);

    AutomatedTest test2 = new AutomatedTest(TestList._2DayTest);
    RunAutoTest(test2);

    AutomatedTest test3 = new AutomatedTest(TestList._3DayTest);
    RunAutoTest(test3);

    AutomatedTest test4 = new AutomatedTest(TestList._4DayTest);
    RunAutoTest(test4);
}  

So 4 objects are created and run, and this is done 20 times.
My question is how should I properly dispose/destruct these objects? I don't want to assume these are garbage collected, but I'm new to implementing desctructors.

like image 553
Nick Sinas Avatar asked Dec 12 '25 12:12

Nick Sinas


2 Answers

As long as you don't use any objects that implement IDisposable, you shouldn't have to manually dispose or destruct.

like image 190
therealmitchconnors Avatar answered Dec 14 '25 03:12

therealmitchconnors


The destructor for a class is called when your object gets garbage collected. In a managed programming language like c# you do not have control over when the garbage collector will run and execute your destructor. Garbage collection is taken care of by the CLR (common language run time) when it sees that the object is no longer being referenced or used later in the program. In your example, considering the code

AutomatedTest test1 = new AutomatedTest(TestList._1DayTest);
RunAutoTest(test1);

After executing the RunAutoTest(test1), the 'test1' reference variable is no longer used and will be available for garbage collection. The actual garbage collection process however might not run immediately and there is no way you can ensure it to run at a specific time. If within your AutomatedTest class you are making use of resources like opening a FileStream etc , you would need to free up these resources once you are done using an object of that class. This can be done by having your class implement the IDisposable interface in the following manner

class AutomatedTest:IDisposable
    {
        public void Dispose()
        {
            //free up any resources
        }
    }

Once your class implements IDisposable, you can use it by wrapping it's creation within an 'using' block

 for (int numTests = 0; numTests < 20; numTests++)
        {
            using (AutomatedTest test1 = new AutomatedTest(TestList._1DayTest))
            {
                RunAutoTest(test1);
            }
            //as soon as code exits the 'using' block the dispose method on test1 would be called
            //this is something you cannot guarantee when implementing a destructor

            using (AutomatedTest test2 = new AutomatedTest(TestList._2DayTest))
            {
                RunAutoTest(test2);
            }
            //dispose on test2 will be called here

            ///rest of code
        }  

FYI it is possible to implement the destructor in C# using ~ . The method of implementing IDisposable is preferable over creating a destructor

  class AutomatedTest
    {

        ~AutomatedTest()
        {
            //code will run only on garbage collection
        }
    }
like image 25
nighthawk457 Avatar answered Dec 14 '25 02:12

nighthawk457



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!