Robert MacLean
Robert MacLean

Reputation: 39261

What is the .NET object life cycle?

What is the object life cycle for an object in .NET?

From what I understand it is:

  1. Object created - constructor called (if one exists)
  2. Methods/Properties/Fields used
  3. Object destroyed - Dispose called (if one exists)
  4. Destructor called by GC at some point

Upvotes: 14

Views: 16145

Answers (9)

ZombieMich
ZombieMich

Reputation: 11

The Object Life Cycle

Creating an object: You use the new keyword to instantiate the new object.

  1. A block of memory is allocated. This block of memory is big enough to hold the object. (CLR handles the allocation of memory for managed objects)
  2. The block of memory is converted to an object. The object is initialized. (You can control this step by implementing a constructor)

Destroying an Object: You use destruction to reclaim any resources used by that object.

  1. The object is cleaned up; for example, by releasing any unmanaged resources used by the application, such as file handles and database connections. (You can control this step by implementing a destructor.)
  2. The memory used by the object is reclaimed.

The CLR handles the release of memory used by managed objects; however, if you use unmanaged objects, you may need to manually release the memory used by these items.

Upvotes: 1

Theofanis Pantelides
Theofanis Pantelides

Reputation: 4854

Here is an example class that uses all the information available in the articles provided here. I have already spent hours testing things out, and this is what works best for me.

/*********************************
 * Author:  Theofanis Pantelides *
 *   Date:  23 Jun 2009          *
 *********************************/

using System;
using System.IO;

public class MyClass : IDisposable
{
    String oFile;
    Stream oStream;

    public MyClass(String _File)
    {
        oStream = File.OpenRead(oFile = _File);
        // Initialize
    }

    ~MyClass()
    {
        this.Dispose();
        // Destruct
    }

    public void doSomething()
    {
        // do Whatever it is you are trying to do
    }

    #region IDisposable Members

    /// <summary>
    /// Dispose all resources used by instance of class
    /// and update Garbage Collector information
    /// </summary>
    public void Dispose()
    {
        if (oStream != null)
        {
            oStream.Dispose(); // Dispose using built in functions
            GC.SuppressFinalize(oStream); // No need for Garbage Collector
        }

        oStream = null;  // Nullify it.
    }

    #endregion
}

Usage:

using(MyClass mc = new MyClass(@"c:\temp\somefile.txt"))
{
  mc.doSomething();
}

You can even use the same declaration twice as it does not exist outside the 'using'.

using(MyClass mc = new MyClass(@"c:\temp\somefile.txt"))
{
  mc.doSomething();
}

using(MyClass mc = new MyClass(@"c:\temp\somefile.txt"))
{
  mc.doSomething();
}

Upvotes: 1

Hans Malherbe
Hans Malherbe

Reputation: 3018

In C#, member initializers are called before the constructor while in VB.NET, they are called after the constructor.

The runtime does not guarantee calling Finalize at all.

Dispose and Finalize is for cleaning up unmananged resources only. Trying to clean up managed resources in a finalizer by e.g. calling Dispose on inner members will land you in trouble because they may have been finalized already.

I like to keep things simple and just use the finalizer to detect and log a nasty error message telling the developer to go fix the code. Trying to figure out whether it is safe to do the work Dispose was supposed to do is too easy to get wrong and usually not worth spending cycles on.

Upvotes: 0

Matthew Whited
Matthew Whited

Reputation: 22443

0) If Static Constructor exists on Object it is called the first time and object of that type is created or referenced

Upvotes: 1

Hans Kesting
Hans Kesting

Reputation: 39283

A point about the constructor:

Every class has one, as one will be generated by the compiler if you don't code it yourself. And the first thing this does (unless specified otherwise), is to call the ctor of it's parent type.

Upvotes: 1

Marc Gravell
Marc Gravell

Reputation: 1062855

Just as an edge case... you can create objects without using the ctor at all:

class Foo {  
    public Foo() {
        message += "; ctor";
    }
    string message = "init";
    public string Message { get { return message; } }
}
static class Program {
    static void Main() {
        Foo foo = new Foo();
        Console.WriteLine(foo.Message); // "init; ctor"
        Foo bar = (Foo)System.Runtime.Serialization.FormatterServices
            .GetSafeUninitializedObject(typeof(Foo));
        Console.WriteLine(bar.Message); // null
    }
}

Upvotes: 17

David Schmitt
David Schmitt

Reputation: 59346

Here are the steps I know of:

  1. load the assembly
  2. execute static initialisers
  3. "new" call:
    1. allocate memory
    2. execute non-static initialisers
    3. execute constructor
  4. the instance is now ready to be used
  5. after the last reference to the object has vanished: if the object has no finalizer, it is now ready for collection; if the object has a finalizer, it is put on the finalizer queue.
  6. (optional) the objects from the finalizer queue have their finalizer called in a special thread; if there is still no reference from the application to the object, it too becomes now eligible for garbage collection
  7. the garbage collector deallocates memory

As others already have pointed out, Dispose() must be called by the user since the runtime won't act on it.

Upvotes: 6

Dmitry Risenberg
Dmitry Risenberg

Reputation: 2381

Here is a detailed descriptin of the question. First, Dispose is not called by runtime, you have to call it yourself. There are also no destructors, but finalizers: if an object overrides a Finalized method, it is called when the object is no longer accessible for the application. It may happen that during finalization the object becomes accessible again (for example, stores a reference to itself in a global object), so it returns to step 2 of your model. There are also methods in GC object that let the user control object finalization.

Upvotes: 5

Sander Rijken
Sander Rijken

Reputation: 21615

Dispose doesn't get called automatically; you need to call it, or use a using block, eg.

using(Stream s = File.OpenRead(@"c:\temp\somefile.txt"))
    // Do something with s

The finalizer only gets called by the GC if it exists. Having a finalizer causes your class to be collected in 2 steps; first the object is put in the finalizer queue, then the finalizer is called and the object is collected. Objects without finalizers are directly collected.

The guideline is that Dispose gets rid of managed and unmanaged resources, and the finalizer only cleans up unmanaged resources. When the Dispose method has freed the unmanaged resources it can call GC.SuppressFinalize to avoid the object from living long to be put on the finalizer queue. See MSDN for a correct sample of the dispose pattern.

Upvotes: 22

Related Questions