IT SOLUTIONS
Your full service technology partner! 
-Collapse +Expand
To/From Code
   ► KBTo/From GuidesReferenceOOP Details  Print This     

Destructor (Cross Ref > OOP Details)

Destructor

General Info: Class Destructor

A special class method called when an object instance of a class is destroyed. With some languages they are called when the object instance goes out of scope, with some languages you specifically have to call the destructor in code to destroy the object, and others use a garbage collector to dispose of object instances at specific times.

Desctructors are commonly used to free the object instance but with languages that have a garbage collector object instances are disposed of when appropriate. Either way, destructors or their equivalent are commonly used to free up resources allocated in the class constructor.

Languages Focus

Are object instances freed with a garbage collector? Or, do you have to destroy object instances.

Access VBA: 

When an object instance is destroyed, Access VBA calls a special parameter-less sub named Class_Terminate. For example, when the variable falls out of scope. Since you cannot specify parameters for this sub, you also cannot overload it.

To explicitly destroy an object, use Set YourClass = nothing.

When an object instance is created from a class, Access VBA calls a special sub called Class_Initialize.

More Info / Comment

Linked Certification Question(s)

The following are practice certification questions with answers highlighted. These questions were prepared by Mike Prestwood and are intended to stress an important aspect of this KB post. All our practice questions are intended to prepare you generally for passing any certification test as well as prepare you for professional work.

Advanced

1 Advanced Level Question

Question #1: Multiple Choice

In Access object oriented programming, when an object instance is destroyed, Access VBA calls a special parameter-less sub named what?

Answer:
1. 

Class_Destroy

2. 

Class_Free

3. 

Object_Destroy

4. 

Class_Terminate

5. 

Object_Terminate

More Info

Definition:  Class Destructor
 

ASP Classic:   Class_Terminate

When an object instance is destroyed, ASP calls a special parameter-less sub named Class_Terminate. For example, when the variable falls out of scope. Since you cannot specify parameters for this sub, you also cannot overload it.

To explicitly destroy an object, use Set YourClass = nothing. If the Class object is explicitly destroyed, the client returns with the script engine error details.

When an object instance is created from a class, ASP calls a special sub called Class_Initialize.

Syntax Example:
Class Cyborg
  Public Sub Class_Terminate
    Response.Write "<br>Class destroyed"
End Sub
End Class

Working Example

The following working example contains both a constructor and destructor, ASP's Class_Initialize and Class_Terminate subs. In this example, we are explicitly destroying the object by using Set MyRobot = Nothing. In ASP Classic, it is recommended that you explicitly destroy all objects.

<%@LANGUAGE=VBScript%>
<%Option Explicit%>
<html>
<body>
  
<%
Dim MyRobot
Set MyRobot = new Cyborg
Response.Write "<br>My robot's name is " & MyRobot.CyborgName & "."
  
//Explicitly destroy object.
Set MyRobot = Nothing
%>
  
</body>
</html>
  
<%
Class Cyborg
 Public CyborgName
 
 Public Sub Class_Initialize
  Response.Write "<br>Class created"
  CyborgName = "Cameron"
 End Sub 
  
 Public Sub Class_Terminate
  Response.Write "<br>Class destroyed"
 End Sub
 
End Class

%> 


Linked Certification Question(s)

The following are practice certification questions with answers highlighted. These questions were prepared by Mike Prestwood and are intended to stress an important aspect of this KB post. All our practice questions are intended to prepare you generally for passing any certification test as well as prepare you for professional work.

Advanced

1 Advanced Level Question

Question #1: Multiple Choice

In ASP Classic object oriented programming, when an object instance is destroyed, Access VBA calls a special parameter-less sub named what?

Answer:
1. 

Class_Terminate

2. 

Finalize

3. 

Object_Terminate

4. 

Class_Finalize

5. 

Free

More Info

Code:  ASP Classic Destructor (Class_Terminate)
Definition:  Class Destructor

C#:  "Finalizer" ~ClassName

In C# you cannot explicitly destroy a managed object. Instead, the .Net Framework's garbage collector (GC) takes care of destroying all objects. The GC destroys the objects only when necessary. Some situations of necessity are when memory is exhausted or you explicitly call the System.GC.Collect() method. In general, you never need to call System.GC.Collect().

In .Net, a finalizer is used to free non-managed objects such as a file or network resource. In C#, a finalizer is a method with the same name as the class but preceded with a tilde (as in ~ClassName). The finalizer method implicity creates an Object.Finalize method (you cannot directly call nor override the Object.Finalize method). Because you don't know when the garbage collector will call your finalizer, Microsoft recommends you implement the IDisposable interface for non-managed resources and call it's Dispose() method at the appropriate time.

Syntax Example:
class Cyborg {
public:
//Destructor for class Cyborg.
~Cyborg();
  {
  //Free non-managed resources here.
  }
};

Working WinForms Example

The following demonstrates using a finalizer and System.GC.Collect(). I placed a MessageBox.Show() in the finalizer so you can see when it is called. The finalizer gets called when the compiler needs to free resources or you call System.GC.Collect(). You'll notice that although the local variable in the button click event falls out of scope, your finalizer is not called until either you close the form or click the button that calls System.GC.Collect().

Create a form with two buttons and add code as follows:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
  
namespace CR_Constructor
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
  
    private void button1_Click(object sender, EventArgs e)
{
      //Create and use object instance.
      Cyborg MyRobot = new Cyborg("Cameron");
MessageBox.Show("My robot's name is " + MyRobot.CyborgName);
}
  
    private void button2_Click(object sender, EventArgs e)
{
      //Explicitly call garbage collector (never required for managed code).
System.GC.Collect();
}
}
  
  public class Cyborg: Object
{
public string CyborgName;
    
    //Constructor.
    public Cyborg(string pName)
{
CyborgName = pName;
}
  
    //Finalizer.
    ~Cyborg()
{
MessageBox.Show("Free non-managed resources here.");
}

}

}

 

Implementing IDisposable

If you wish to have control over freeing the objects you create (either managed or unmanaged object instances), use the IDisposable interface and add it to your class and implement according to the standard IDisposable pattern.

Add IDisposable to Your Class

public class Cyborg: Object, IDisposable
{
  private bool disposed = false;
  // Do not make this method virtual.
// Don't let a descendant class override this method.
public void Dispose()
{
Dispose(true);
  
    // This object will be cleaned up by the Dispose method.
// Call GC.SupressFinalize to remove from GC queue.
GC.SuppressFinalize(this);
}
  
  // Dispose of managed and/or unmanaged resources.
  private void Dispose(bool disposing)
  {
    if(!this.disposed)
    {
      if(disposing)
      {
        //Free managed resources here.
      }
      
      // Free unmanaged resources here.
      
      //Indicated disposing completed.
      disposed = true;
    }
  }
  
  //Finalizer.
  ~Cyborg()
{
    Dispose(false);
}
}

Using IDisposable

Once implemented you can free object instances by calling Dispose.

Cyborg MyRobot1 = new Cyborg();
 
MyRobot1.CyborgName = "John";
MessageBox.Show("My robot's name is " + MyRobot1.CyborgName);
  
MyRobot1.Dispose(); 

Working IDisposable Example

In the following example, we implement the IDisposable interface in our Cyborg class from above and call Dispose in the button's click event. You'll notice that whether you click our second button that calls System.GC.Collect or exit the form, the dialog in our finalizer is never displayed because the managed object instances that were used are already disposed of properly. In this implementation, if you forget to call Dispose, the GC will clean up the object at an appropriate time and call your finalizer.

Setup form:

"Picture

After you implement the code below, perform the following use cases:

  • Click the Instantiate Object Only button and close the form. The GC cleans up upon close of the form.
  • Click the Instantiate Objects Only button then click the GC.Collect button. The GC cleans up at that time.
  • Click the Instantiate and Dispose button. Notice the objects are disposed of in the click event. Then close the form and notice your finalizer code is never executed.

Complete Code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace CR_Constructor
{
  public partial class Form1 : Form
  {
    public Form1()
    {
      InitializeComponent();
    }
  
    private void button1_Click(object sender, EventArgs e)
    {
      Cyborg MyRobot1 = new Cyborg();
      MyRobot1.CyborgName = "John";
      MessageBox.Show("My robot's name is " + MyRobot1.CyborgName);
  
      Cyborg MyRobot2 = new Cyborg("Cameron");
      MessageBox.Show("My robot's name is " + MyRobot2.CyborgName);
    }
  
    private void button2_Click(object sender, EventArgs e)
    {
      System.GC.Collect();
    }
  
    private void button3_Click(object sender, EventArgs e)
    {
      Cyborg MyRobot1 = new Cyborg();
      MyRobot1.CyborgName = "John";
      MessageBox.Show("My robot's name is " + MyRobot1.CyborgName);
  
      Cyborg MyRobot2 = new Cyborg("Cameron");
      MessageBox.Show("My robot's name is " + MyRobot2.CyborgName);
  
      MyRobot1.Dispose();
      MyRobot2.Dispose();
    }
  }

  public class Cyborg: Object, IDisposable
  {
    private bool disposed = false;
  
    public void Dispose()  
    {
      Dispose(true);
      GC.SuppressFinalize(this);
      MessageBox.Show("Dispose executed.");
    }
  
    private void Dispose(bool disposing)  
    {
      if(!this.disposed)
      {
        if(disposing)
        {
          //Free managed resources here.     
        }
       
        // Free unmanaged resources here.
        disposed = true;
      } 
    }
  
    public string CyborgName;
  
    public Cyborg() { }
  
    public Cyborg(string pName)
    {
      CyborgName = pName;
    }
  
    ~Cyborg()
    {
      MessageBox.Show("If we call Dispose, does this execute? No.");
      Dispose(false);
    }
  }
}

Q. If I implement IDisposable, can I also let the garbage collector free my objects?

A. It depends on how you implemented IDisposable and how you are using resources. In general, if you implement IDisposable you should take ownership of calling Dispose for each object instance you create. However, in the simple Working IDisposable Example in this article, you can either call Dispose to free the objects or let the garbage collector free them as demonstrated by the button click events.

Q. If I consume an object that implements IDisposable, should I always call Dispose?

A. In general, yes if it's a shared resource. However, again it depends on why IDisposable was implemented. If Dispose is freeing a resource that may be needed, like a file handle, then yes. There may be exceptions to this rule, but if an object implements IDisposable and the resource is a shared resource, then yes when you create an object instance, you should take ownership and also call Dispose at the appropriate time.



Linked Certification Question(s)

The following are practice certification questions with answers highlighted. These questions were prepared by Mike Prestwood and are intended to stress an important aspect of this KB post. All our practice questions are intended to prepare you generally for passing any certification test as well as prepare you for professional work.

Advanced

1 Advanced Level Question

Question #1: Multiple Choice

Given the following code snippet:

public class Cyborg
{
}
Answer:
1. 

The finalizer method name must be Finalize.

2. 

The finalizer method name must be Destroy.

3. 

The finalizer method name must be Dispose.

4. 

The finalizer method name must be ~Cyborg.

5. 

The finalizer method name can be any method name of your choosing so long as you use the finalizer keyword to indicate this is the finalizer method.

More Info

Code:  C# Constructors (Use class name)
Code:  C# Finalizer (~ClassName)
Definition:  Class Destructor

C++:   ~ClassName

A member function with the same name as the class prefixed with a ~ (tilde). C++ destructors are automatically called when an object goes out of scope, or when you delete a dynamically allocated object. Every class can have only one destructor.

Syntax Example:
class Cyborg {
public:
// Constructor for class Cyborg
Cyborg();
  
// Destructor for class Cyborg
~Cyborg();
};

More Info

Definition:  Class Destructor

C++/CLI:  "Finalizer" ~ClassName

Unlike standard C++, C++/CLI uses the .Net garbage collector to free managed object instances. Prism does not have nor need a true destructor.

In .Net, a finalizer is used to free non-managed objects such as a file or network resource. Because you don't know when the garbage collector will call your finalizer, Microsoft recommends you implement the IDisposable interface for non-managed resources and call it's Dispose() method at the appropriate time.

More Info / Comment

More Info

Definition:  Class Destructor

Corel Paradox:   Not Supported

Delphi:   Free or FreeAndNil

Object Pascal uses a standard virtual destructor named Destroy which is called by the standard Free method. All objects are dynamic, so you need to call MyObject.Free method or the FreeAndNil(MyObject) routine for each object you create.

Syntax Example:
var
MyObject: TObject;
begin
MyObject := TObject.Create;
 
  //Use it...
  
  MyObject.Free
  //Or use...FreeAndNil(MyObject);
end;


Linked Certification Question(s)

The following are practice certification questions with answers highlighted. These questions were prepared by Mike Prestwood and are intended to stress an important aspect of this KB post. All our practice questions are intended to prepare you generally for passing any certification test as well as prepare you for professional work.

Beginner

1 Beginner Level Question

Question #1: Multiple Choice

Given the following code:

var
MyObject: TObject;
begin
MyObject := TObject.Create;
 
  //Use it...  
end;
Answer:
1. 

Delphi has a garbage collector so you do not have to dispose of the object after the "Use it" comment but optionally you can dispose of additional resources created in the constructure overriding the Finalize() method and calling MyObject.Free().

2. 

Delphi does not have a garbage collector so you have to dispose of the object after the "Use it" comment with either MyObject.Free() or FreeAndNil(MyObject).

3. 

Delphi does not have a garbage collector so you have to dispose of the object after the "Use it" comment with MyObject.Dispose().

More Info

Definition:  Class Destructor
 

Delphi Prism:  "Finalizer" finalize()

Unlike Delphi, Delphi Prism uses the .Net garbage collector to free managed object instances. Prism does not have nor need a true destructor.

In .Net, a finalizer is used to free non-managed objects such as a file or network resource. In Prism, you use the keyword finalizer to indicate the method is a finalizer. Each class can implement one and only one finalizer with a method name of finalize(), which is the method name used in Java and VB.Net.

Because you don't know when the garbage collector will call your finalizer, For non-managed resources, Microsoft recommends you implement the IDisposable interface and call it's Dispose() method at the appropriate time.

Syntax Example:
type
  Cyborg = class(IDisposable)
  private
    disposed: Boolean;
    method Dispose(disposing: Boolean);
  public
    method Dispose;
    finalizer Finalize;
  end;

Important Notes

  • Each class has one and only one finalizer.
  • The name of the finalizer is always Finalize.
  • You cannot call a finalizer, nor can you overload it.
  • You cannot predict with certainty when it will be called.

Working WinForms Example

The following demonstrates using a finalizer and System.GC.Collect(). I placed a MessageBox.Show() in the finalizer so you can see when it is called. The finalizer gets called when the compiler needs to free resources or you call System.GC.Collect(). You'll notice that although the local variable in the button click event falls out of scope, your finalizer is not called until either you close the form or click the button that calls System.GC.Collect().

Create a form with two buttons and add code as follows:

namespace CR_Constructor;
   
interface
  
uses
  System.Drawing,
  System.Collections,
  System.Collections.Generic,
  System.Linq,
  System.Windows.Forms,
  System.ComponentModel;
  
type
  /// <summary>
  /// Summary description for MainForm.
  /// </summary>
  MainForm = partial class(System.Windows.Forms.Form)
  private
    method button1_Click(sender: System.Object; e: System.EventArgs);
    method button2_Click(sender: System.Object; e: System.EventArgs);
  protected
    method Dispose(disposing: Boolean); override;
  public
    constructor;
  end;
  
  Cyborg = class(System.Object)
  private
  public
    property CyborgName: String;  //Property using implicit syntax.
    constructor();
    constructor(pName: String);
  
    //This is the full version of a finalizer.
    finalizer Finalize;
  
    //As with constructors, you could have just used the keyword.
    //finalizer;
  end;
implementation
{$REGION Construction and Disposition}
constructor MainForm;
begin
  //
  // Required for Windows Form Designer support
  //
  InitializeComponent();
  //
  // TODO: Add any constructor code after InitializeComponent call
  //
end;
  
method MainForm.Dispose(disposing: Boolean);
begin
  if disposing then begin
    if assigned(components) then
      components.Dispose();
    //
    // TODO: Add custom disposition code here
    //
  end;
  inherited Dispose(disposing);
end;
{$ENDREGION}
  
method MainForm.button1_Click(sender: System.Object; e: System.EventArgs);
var
  MyRobot1: Cyborg;
  MyRobot2: Cyborg;
begin
  MyRobot1 := New Cyborg;
  MyRobot1.CyborgName := "John";
  MessageBox.Show("My robot's name is " + MyRobot1.CyborgName + ".");
  
  MyRobot2 := New Cyborg("Cameron");
  MessageBox.Show("My robot's name is " + MyRobot2.CyborgName + ".");
end;

method MainForm.button2_Click(sender: System.Object; e: System.EventArgs);
begin 
  System.GC.Collect;
end;
  
constructor Cyborg();
begin
end;
  
constructor Cyborg(pName: String);
begin
  CyborgName := pName;
end;
  
finalizer Cyborg.Finalize;
begin
  MessageBox.Show("In finalizer.");
end;

end.

Implementing IDisposable

If you wish to have control over freeing the objects you create (either managed or unmanaged object instances), use the IDisposable interface and add it to your class and implement according to the standard IDisposable pattern.

Add IDisposable to Your Class

//
//Interface
//
//1. Add IDisposable interface to inheritance syntax
//   and add two Dispose methods and a member field boolean.
Cyborg = class(System.Object, IDisposable)
private
  disposed: Boolean;
  method Dispose(disposing: Boolean);
public
  finalizer Finalize;
  method Dispose;
end;
  
//
//Implementation
//
//2. Implement the two dispose methods.
method Cyborg.Dispose;
begin
  Dispose(true);
  
  GC.SuppressFinalize(self);
end;
  
method Cyborg.Dispose(disposing: Boolean);
begin
  if not disposed then
  begin
    if disposing then
    begin
      // Dispose of managed resources.
    end;
  
    // Dispose of unmanaged resources
    disposed := true;
  end
end;
  
//3. Set your boolean to false in finalizer
//   using your Dispose() method. 
finalizer Cyborg.Finalize;
begin
  Dispose(false);
end;

Using IDisposable

Once implemented you can free object instances by calling Dispose.

var MyRobot1: Cyborg;
 
MyRobot1 := New Cyborg;
MyRobot1.CyborgName := "John";
MessageBox.Show("My robot's name is " + MyRobot1.CyborgName + ".");
 
MyRobot1.Dispose;

Working IDisposable Example

In the following example, we implement the IDisposable interface in our Cyborg class from above and call Dispose in the button's click event. You'll notice that whether you click our second button that calls System.GC.Collect or exit the form, the dialog in our finalizer is never displayed because the managed object instances that were used are already disposed of properly.

namespace CR_Constructor;
interface
uses
  System.Drawing,
  System.Collections,
  System.Collections.Generic,
  System.Linq,
  System.Windows.Forms,
  System.ComponentModel;
type
  /// <summary>
  /// Summary description for MainForm.
  /// </summary>
  MainForm = partial class(System.Windows.Forms.Form)
  private
    method button1_Click(sender: System.Object; e: System.EventArgs);
    method button2_Click(sender: System.Object; e: System.EventArgs);
  protected
    method Dispose(disposing: Boolean); override;
  public
    constructor;
  end;
  
  Cyborg = class(System.Object, IDisposable)
  private
    disposed: Boolean;
    method Dispose(disposing: Boolean);
  public
    property CyborgName: String;
    constructor;
    constructor(pName: String);
    finalizer Finalize;
    method Dispose;
  end;
implementation
  
{$REGION Construction and Disposition}
constructor MainForm;
begin
  //
  // Required for Windows Form Designer support
  //
  InitializeComponent();
  //
  // TODO: Add any constructor code after InitializeComponent call
  //
end;
  
method MainForm.Dispose(disposing: Boolean);
begin
  if disposing then begin
    if assigned(components) then
      components.Dispose();
    //
    // TODO: Add custom disposition code here
    //
  end;
  inherited Dispose(disposing);
end;
{$ENDREGION}
  
method MainForm.button1_Click(sender: System.Object; e: System.EventArgs);
begin
  var MyRobot1: Cyborg;
  var MyRobot2: Cyborg;
  
  MyRobot1 := New Cyborg;
  MyRobot1.CyborgName := "John";
  MessageBox.Show("My robot's name is " + MyRobot1.CyborgName + ".");
  
  MyRobot2 := New Cyborg("Cameron");
  MessageBox.Show("My robot's name is " + MyRobot2.CyborgName + ".");
  
  MyRobot1.Dispose;
  MyRobot2.Dispose;

end;

method MainForm.button2_Click(sender: System.Object; e: System.EventArgs);
begin
  System.GC.Collect;
end;
  
constructor Cyborg();
begin

end;
  
constructor Cyborg(pName: String);
begin
  CyborgName := pName;
end;

finalizer Cyborg.Finalize;
begin
 
Dispose(false);
  
  //This dialog never shows demonstrating the 
  //finalizer is not called by the garbage collector.

  MessageBox.Show("In finalizer");
end;

method Cyborg.Dispose;
begin
  Dispose(true);
  
  GC.SuppressFinalize(self);
  MessageBox.Show("In Dispose");
end;
  
method Cyborg.Dispose(disposing: Boolean);
begin
  if not disposed then
  begin
    if disposing then
    begin
      // Dispose of managed resources.
    end;
  
    // Dispose of unmanaged resources
    disposed := true;
  end
end;
end.

Q. If I implement IDisposable, can I also let the garbage collector free my objects?

A. It depends on how you implemented IDisposable and how you are using resources. In general, if you implement IDisposable you should take ownership of calling Dispose for each object instance you create. However, in the simple Working IDisposable Example in this article, you can either call Dispose to free the objects or let the garbage collector free them as demonstrated by the button click events.

Q. If I consume an object that implements IDisposable, should I always call Dispose?

A. In general, yes if it's a shared resource. However, again it depends on why IDisposable was implemented. If Dispose is freeing a resource that may be needed, like a file handle, then yes. There may be exceptions to this rule, but if an object implements IDisposable and the resource is a shared resource, then yes when you create an object instance, you should take ownership and also call Dispose at the appropriate time.



Linked Certification Question(s)

The following are practice certification questions with answers highlighted. These questions were prepared by Mike Prestwood and are intended to stress an important aspect of this KB post. All our practice questions are intended to prepare you generally for passing any certification test as well as prepare you for professional work.

Beginner

1 Beginner Level Question

Question #1: True or False?

Each class can have one and only one finalizer.

Answer:
  • True
  • False
  • Intermediate

    1 Intermediate Level Question

    Question #2: True or False?

    The traditional name for a finalizer is Finalize but you can call it anything you want.

    Answer:
  • True
  • False
  • More Info

    Definition:  Class Destructor
    Code:  Delphi Prism Constructors (constructor + class name)
    Code:  Delphi Prism Finalizer (finalize())

    Java:  "finalize" finalize()

    Java has a garbage collection algorythm that runs as a background task so it has no destructors. You can use the finalize() method to close additonal resources such as file handles.

    Syntax Example:
    protected void finalize() throws Throwable {
    try {
    close(); // close open files
    } finally {
    super.finalize();
    }
    }

    More Info

    Definition:  Class Destructor

    VB Classic: 

    When an object instance is destroyed, VB6 calls a special parameter-less sub named Class_Terminate. For example, when the variable falls out of scope. Since you cannot specify parameters for this sub, you also cannot overload it.

    To explicitly destroy an object, use Set YourClass = nothing.

    When an object instance is created from a class, VB6 calls a special sub called Class_Initialize.

    More Info / Comment

    Linked Certification Question(s)

    The following are practice certification questions with answers highlighted. These questions were prepared by Mike Prestwood and are intended to stress an important aspect of this KB post. All our practice questions are intended to prepare you generally for passing any certification test as well as prepare you for professional work.

    Advanced

    1 Advanced Level Question

    Question #1: Multiple Choice

    In VB Classic object oriented programming, when an object instance is destroyed, VB calls a special parameter-less sub named what?

    Answer:
    1. 

    Finalize

    2. 

    Object_Terminate

    3. 

    Class_Finalize

    4. 

    Class_Terminate

    5. 

    Free

    More Info

    Definition:  Class Destructor
     

    VB.Net:  "Finalizer" Finalize()

    In VB.Net you cannot explicitly destroy a managed�object. Instead, the .Net Framework's garbage collector (GC) takes care of destroying all objects. The GC destroys the objects only when necessary. Some situations of necessity are when memory is exhausted or you explicitly call the System.GC.Collect() method. In general, you never need to call System.GC.Collect().

    In .Net, a finalizer is used to free non-managed objects such as a file or network resource. In VB.Net, a finalizer is an overridden sub called Finalize. Because you don't know when the garbage collector will call your finalizer, Microsoft recommends you implement the IDisposable interface for non-managed resources and call it's Dispose() method at the appropriate time.

    Syntax Example:
    Class Cyborg
    � Protected Overrides Sub Finalize()
    ��� 'Free non-managed resources here.
    ��� MyBase.Finalize()
    � End Sub
    End Class

    Working WinForms Example

    The following demonstrates using a finalizer and System.GC.Collect(). I placed a MessageBox.Show() in the finalizer so you can see when it is called. The finalizer gets called when the compiler needs to free resources. You'll notice that although the local variable in the button click event falls out of scope, your finalizer is not called until either you close the form or click the button that calls System.GC.Collect().

    Create a form with two buttons and add code as follows:

    Public Class Form1
      Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        'Create and use object instance.
        Dim MyRobot2 As New Cyborg("Cameron")
        MessageBox.Show("My robot's name is " & MyRobot2.CyborgName & ".")
      End Sub
     
      Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        'Explicitly call garbage collector (never required for managed code).
        System.GC.Collect()
      End Sub
    End Class
      
    Public Class Cyborg
      Public CyborgName As String
        
      'Constructor.
      Public Sub New(ByVal pName As String)
        CyborgName = pName
      End Sub
      
      'Destructor/finalizer.
      Protected Overrides Sub Finalize()
        MessageBox.Show("Free non-managed resources here.")
        MyBase.Finalize()
      End Sub
    End Class

    Cannot Call Finalize()

    Although an Object.Finalize() method is implicitly created even when you do not create a finalizer, you still cannot call it directly. In button1_click, if you try to call MyRobot2.Finalize(), it fails the following error.

    Error 1 Overload resolution failed because no 'Finalize' is accessible.

    Q. If I implement IDisposable, can I also let the garbage collector free my objects?

    A. It depends on how you implemented IDisposable and how you are using resources. In general, if you implement IDisposable you should take ownership of calling Dispose for each object instance you create. However, in the simple Working IDisposable Example in this article, you can either call Dispose to free the objects or let the garbage collector free them as demonstrated by the button click events.

    Q. If I consume an object that implements IDisposable, should I always call Dispose?

    A. In general, yes if it's a shared resource. However, again it depends on why IDisposable was implemented. If Dispose is freeing a resource that may be needed, like a file handle, then yes. There may be exceptions to this rule, but if an object implements IDisposable and the resource is a shared resource, then yes when you create an object instance, you should take ownership and also call Dispose at the appropriate time.



    Linked Certification Question(s)

    The following are practice certification questions with answers highlighted. These questions were prepared by Mike Prestwood and are intended to stress an important aspect of this KB post. All our practice questions are intended to prepare you generally for passing any certification test as well as prepare you for professional work.

    Advanced

    1 Advanced Level Question

    Question #1: Multiple Choice

    Given the following code snippet:

    Public Class Cyborg
    End Class
    Answer:
    1. 

    The finalizer method name must be ~Cyborg.

    2. 

    The finalizer method name must be Finalize.

    3. 

    The finalizer method name can be any method name of your choosing so long as you use the finalizer keyword to indicate this is the finalizer method.

    4. 

    The finalizer method name must be Destroy.

    5. 

    The finalizer method name must be Class_Terminate.

    More Info

    Definition:  Class Destructor
    Code:  VB.Net Finalizer (Finalize())




    Go ahead!   Use Us! Call: 916-726-5675  Or visit our new sales site: 
    www.prestwood.com


    ©1995-2024 Prestwood IT Solutions.   [Security & Privacy]