[
Advertise | Submit Code | About us | Contact us | Link us
]
Go!
Membership Services
Login
Register

Home
C# General

General

C# Language

Design & Architecture

Algorithms

Database

Security

Active Directory

COM Interop

Remoting
C# Windows Forms

General

Combo and List boxes

Miscellaneous Controls

Button Controls

Edit Controls
Cutting Edge

ASP.NET 2.0

Visual Studio 2005

Windows Longhorn

SQL Server 2005
C# Multimedia and GDI+

General

DirectX

GDI+

Audio
Internet & Web

General

Images and multimedia

Database

Utilities

Security

ASP.NET Controls

Design and Architecture

Webservices
.NET

General

Design & Architecture

Algorithms

Database

Security

Active Directory

COM Interop

Remoting

ADO.NET

XML.NET

Tools

Enterprise

IDE
Visual Basic .NET

VB.NET General

VB.NET Controls
General Reading

.NET Books Review

Product Showcase

Book Chapters

Business Design & Strategy
Community

Discuss

Job Board

Discussion

CodeXchange
DeveloperLand

Advertise

Submit Code

About us

Contact us

Link us
Miscellaneous

Favorite Links

Downloads

Programming Sites

Top Stories
Regular Expressions

E-Mail

Date/Time
Home > C# General > C# Language
Constructors in C#
Posted by on Thursday, August 26, 2004 (EST)

An detailed explanation of constructors, with reference to the language specification.

This article has been viewed: 2,474 times
Technology: C# Language.

Contents

In the C# newsgroup, there was recently (at the time of writing) a discussion about various aspects of constructors. This page provides most of the important bits about how I believe constructors work in C#, including references to the language specification to back them up. If you disagree with anything in this page, I ask you to follow the language specification link to the appropriate section. If you then believe I'm incorrectly interpreting the spec, please mail me [^] with details. The ECMA spec and the MS spec are identical as far as I've seen, apart from how they number their sections. I'll give links to both so you can use whichever you feel more comfortable with. In fact,

A little terminology...

The C# language spec refers to two types of constructors: instance constructors and static constructors. This page only deals with instance constructors, and I'll just call them constructors for short. That's what most people understand by the term "constructor" anyway. Static constructors are the equivalent of static initializers in Java - they give the code which is executed when a class is first used.

Top Go to Table of Contents

What is a constructor?

(ECMA [^]) (MS [^]).
To quote the spec, "An instance constructor is a member that implements the actions required to initialize an instance of a class." That's actually a pretty good description on its own. A constructor is invoked when you use the "new" operator, or use the various methods of reflection to create an instance of a class.

Top Go to Table of Contents

What do constructors look like?

A looks very much like a method, but with no return type and a name which is the same as the name of the class. (The modifiers you can use with a constructor are slightly different, however - see the spec for more information about that.) Here's a short class to use as an example:

public class MySimpleClass
{
    public MySimpleClass (int x)
    {
        Console.WriteLine (x);
    }
}

This class has a single constructor, which takes an int as a parameter, and prints that int's value to the console.

Top Go to Table of Contents

Constructor Initializers

Now, in fact, there's something else going on here, which is hidden by the compiler. The above is actually equivalent to:

public class MySimpleClass
{
    public MySimpleClass (int x) : base()
    {
        Console.WriteLine (x);
    }
}

(ECMA [^]) (MS [^]).
Note the base() bit. That's saying which other constructor should be invoked before any of the rest of the code in the constructor runs. Every constructor of every class other than plain object does this, either explicitly or implicitly. There are two forms of constructor initializer - one which calls a base class constructor (as above) and one which calls another constructor from this class, using the this (...) syntax. There must always be a "chain" of constructors which runs constructors all the way up the class hierarchy. Every class in the hierarchy will have a constructor invoked, although some of those constructors may not explicitly appear in the code. (See the section on default constructors, later.) The parameters (if any) within the brackets of base(...) or this(...) are passed as the parameters to the invoked constructors. They can be the parameters given in the constructor declaration, but don't have to be. Here's an example:

public class MyBaseClass
{
    // Invoke the parameterless constructor in object
    public MyBaseClass (int x) : base() 
    {
        Console.WriteLine (
"In the base class constructor taking an int, which is "+x);
    }
}

public class MyDerivedClass : MyBaseClass
{
    // Invoke the MyDerivedClass constructor taking an int
    public MyDerivedClass () : this (5) 
    {
        Console.WriteLine (
"In the derived class parameterless constructor.");
    }

    // Invoke the MyBaseClass constructor taking an int
    public MyDerivedClass (int y) : base (y+1) 
    {
        Console.WriteLine (
"In the derived class constructor taking an int parameter.");
    }
              
    // Invoke the MyBaseClass constructor taking an int
    public MyDerivedClass (string x) : base (10) 
    {
        Console.WriteLine (
"In the derived class constructor taking a string parameter.");
    }
}

With the above code, a bit of code saying new MyDerivedClass(); would invoke the MyDerivedClass parameterless constructor, which would in turn invoke the MyDerivedClass constructor which takes an int parameter (with 5 as that parameter value), which would in turn invoke the MyBaseClass constructor which takes an int parameter (with 6 as that parameter value). Note that the specified constructor is run before the constructor body, so the result of new MyDerivedClass(); would be the following output on the console:

In the base class constructor taking an int, which is 6
In the derived class constructor taking an int parameter.
In the derived class parameterless constructor.

Not all constructors in the hierarchy need to be invoked (as demonstrated above - the constructor taking a string parameter is not invoked at all when you do new MyDerivedClass();) but as I said earlier, there must be at least one constructor invoked in each class in the hierarchy.

Top Go to Table of Contents

Default constructor initializers

(ECMA [^]) (MS [^]), second paragraph.
Any constructor which doesn't have a constructor initializer has one provided for it by the constructor. The initializer is of the form base() - in other words, a call to the base class's parameterless constructor. You'll get a compile-time error if you don't provide a constructor initializer and the base class doesn't have an accessible parameterless constructor. (Note, however, that it may have one without you putting one in yourself - see the next section.)

Top Go to Table of Contents

Default constructors

(ECMA [^]) (MS [^])
If you don't specify any constructors at all, a default constructor is provided by the compiler. This default constructor is a parameterless constructor with no body, which calls the parameterless constructor of the base class. In other words:

public class MySimpleClass
{
    int someMemberVariable;
}

... is exactly equivalent to:

public class MySimpleClass
{
    int someMemberVariable;
                
    public MySimpleClass() : base()
    {
    }
}

Following from the previous section, this means that if the base class has no accessible parameterless constructor (including a default one), you get a compile-time error if the derived class doesn't have any constructors - because the default constructor will implicitly try to call a parameterless constructor from the base type.

If the class is abstract, the default constructor provided has protected accessibility; otherwise it has public accessibility.

Top Go to Table of Contents

Instance variable initializers

(ECMA [^]) (MS [^])
When a member variable declaration also has an assignment, that's called a variable initializer. All the variable initializers for a class are implicitly run directly before the invocation of whichever base class constructor is invoked. (Note that this is a change from a previous version of the page, where I believed that they were invoked after the base constructor, as they are in Java.) Here's a simple example of instance variable initializers:

public class MySimpleClass
{
    int someMemberVariable = 10;
                
    public MySimpleClass()
    {
        Console.WriteLine ("someMemberVariable={0}", someMemberVariable);
    }
}

The output of the above is 10 when a new instance is created, whereas without the instance variable initializer, it would be 0 (the default value for instance variables of type int). Demonstrating the difference between Java and C# in terms of when the instance variable initializers are run requires calling an overridden method from the base class constructor. This is a really bad idea - wherever possible, only call non-virtual methods from constructors, and if you absolutely must call a virtual method, document very carefully that it is called from the constructor, so that people wishing to override it are aware that their object may not be in a consistent state when it is called (as their own constructor won't have run yet). Here's an example:

public class MyBaseClass
{
    public MyBaseClass ()
    {
        Console.WriteLine (this.ToString());
    }
}

public class MyDerivedClass : MyBaseClass
{
    string name="hello";
    
    public MyDerivedClass : base()
    {
        Console.WriteLine (this.ToString());
    }

    public override string ToString()
    {
        return name;
    }
}

When a new instance of MyDerivedClass is created in C#, the output is:

hello
hello

The first line is hello because the instance variable initializer for the name variable has run directly before the base class constructor. The equivalent code in Java syntax would output:

null
hello

Here the first line is null because the instance variable initializer for the name variable only runs directly after the base class constructor has returned (but before ToString is called for the second time).

Top Go to Table of Contents

Constructors are not inherited

(ECMA [^]) (MS [^]), second paragraph from the bottom.
Constructors are not inherited. In other words, just because a base class has a constructor taking a certain list of parameters doesn't mean that a derived class has a constructor taking that list of parameters. (It can, by providing one itself, but it doesn't inherit it from the base class.) To demonstrate this, here's an example which doesn't compile:

public class MyBaseClass
{
    public MyBaseClass (int x)
    {
    }
}

public class MyDerivedClass : MyBaseClass
{
    // This constructor itself is okay - it invokes an
    // appropriate base class constructor
    public MyDerivedClass () : base (5)
    {
    }
              
    public static void Main()
    {
        new MyDerivedClass (10);
    }
}

Here, we try to invoke a constructor for MyDerivedClass which takes an int parameter. There isn't one, however, as constructors aren't inherited. The MyBaseClass constructor which takes an int parameter can be invoked by a constructor in MyDerivedClass (as is shown by the parameterless MyDerivedClass constructor) but isn't actually inherited. Removing the "10" from the above code would make it compile and run with no problems - the parameterless MyDerivedClass constructor would be invoked, and that would in turn invoke the MyBaseClass constructor taking an int parameter, with 5 as that parameter value.

Some people have said that they would rather constructors were inherited, making the language act as if all derived classes had constructors with all the parameter lists from the constructors from the base class, and just invoking them with the parameters provided. I believe this would be a very bad idea. Take, for instance, the FileInfo class. You must logically provide a filename when constructing a FileInfo instance, as otherwise it won't know what it's meant to be providing information on. However, as object has a parameterless constructor, constructors being inherited would then mean that FileInfo had a parameterless constructor. Some have suggested that this could be fixed by allowing you to "override" the parameters you didn't want invoked as private, but this goes against the idea that you should never be able to override anything to give it more restrictive access, and also means that class developers would have to change their code every time a new constructor was added to a base class.

Top Go to Table of Contents

About Jon Skeet

Click here if you want to know more about .

Other articles that may interest you

  • Write a Word Add-In – Part 0
  • Write a Word Add-In – Part I
  • Lengthy Operations on Single Thread in .NET Application
  • Learning Draughts
  • Exceptions and Performance
  • Average Rating :

    Discussion Forums
    Got a programming related question? Hopefully someone has the answer... Want to help out other developers? Visit our discussion forums.

    Sponsored by:

    New Articles

  • Exceptions and Performance
    Almost every time exceptions are mentioned in mailing lists and newsgroups, people say they're really expensive.Let's examine that claim, shall we?

  • Creating multilingual websites - Part 1
    Extend the existing globalization capabilities of .NET to create flexible and powerful multilingual web sites. First, create a custom ResourceManager, and then create custom localized-capable server controls to easily deploy multilingual functionality.

  • Parameter passing in C#
    Many people have become fairly confused about how parameters are passed in C#, particularly with regard to reference types. This page should help to clear up some of that confusion

  • Most Popular Articles

  • LDAP, IIS and WinNT Directory Services
    This article explains how to use .NET Directory Services to retrieve and search directory objects, create new directory objects and edit or delete existing directory objects. Describes Active Directory Application Mode (ADAM) and how to use the IIS, WinNT and LDAP directory (ADSI) provider.

  • An in-depth look at WMI and instrumentation, Part II
    WMI stands for Windows Management Instrumentation and, as the name indicates, is about managing your IT infrastructure this article is the second part of a two-part series.

  • An in-depth look at WMI and instrumentation, Part I
    WMI stands for Windows Management Instrumentation and, as the name indicates, is about managing your IT infrastructure this article provides an in-depth look at WMI and MOM 2005

  • New Books

  • Murach's ASP.NET 2.0 Upgrader's Guide: VB Edition
    What’s new and how to use it! That’s what this book delivers if you’re a VB developer who’s interested in upgrading from ASP.NET 1.x to ASP.NET 2.0.

  • C# in easy steps
    Learn to program with Microsoft’s premier programming language. No previous programming knowledge is assumed. With numerous easy-to-follow examples, this title explains the essentials of object-oriented programming with C#.

  • Murach's ASP.NET web programming with VB.NET
    Murach's ASP.NET web programming with VB.NET by Doug Lowe and Anne Prince is a in depth training and reference book for ASP.NET programming using VB.NET. The book builds upon Murach's previous books and covers more advanced concepts for programming ASP.NET pages.

  • Got Code?

    if you have any article , source code , or anything else you'd like to share with this community that you think others might find useful, please submit it here and we will gladly make it available on this site. submit@developerland.com.
    Partners

    All articles are copyrighted by their individual authors unless otherwise specified , everything else Copyright ©2004-2006 DeveloperLand