#590 – Optional Parameters in Constructors

You’ll typically see optional parameters in methods.  But you can also define an optional parameter in a constructor:

        public string Name { get; set; }
        public int Age { get; set; }
        public string FavoriteToy { get; set; }
        public Dog Father { get; set; }
        public Dog Mother { get; set; }

        public Dog(string name, int age = 1, string favToy = "Bone",
            Dog father = null, Dog mother = null)
        {
            Name = name;
            Age = age;
            FavoriteToy = favToy;
            Father = father;
            Mother = mother;
        }

 

            Dog kirby = new Dog("Kirby", 15, "Ball");
            Dog sonOfKirby = new Dog("Ferbie", 2, "Frisbee", kirby);


Optional parameters in constructors avoid the need to chain constructors.

 

#298 – A struct Can Have Several Constructors

You can define more than one constructor for a struct, as long as the method signature for each constructor is different.

    public struct Point3D
    {
        public double x;
        public double y;
        public double z;

        public Point3D(double xi, double yi, double zi)
        {
            x = xi;
            y = yi;
            z = zi;
        }

        public Point3D(int n)
        {
            x = n;
            y = n;
            z = n;
        }
    }

Now you can instantiate a variable of this type in several different ways.

            Point3D pt1 = new Point3D();    // Default parameterless constructor
            Point3D pt2 = new Point3D(10.0, 20.0, 30.0);
            Point3D pt3 = new Point3D(5);

#295 – When Is a Static Constructor Called?

You cannot dictate when a static constructor will be called and you can’t call it directly.

More specifically, a static constructor will be called just before you do one of the following:

  • Create an instance of the type
  • Access any static data in the type
  • Start executing Main method (in the same class as the static constructor)

If we have the following implementation in the Dog class:

        public Dog(string name)
        {
            Console.WriteLine("Dog constructor");
            Name = name;
        }

        public static string Motto = "Wag all the time";

        static Dog()
        {
            Console.WriteLine("Static Dog constructor");
        }

And we create a Dog instance:

 Console.WriteLine("Here 1");
 Dog d1 = new Dog("Kirby");
 Console.WriteLine("Here 2");

We get this output (static constructor called before object instantiation):

Or if we access static data:

            Console.WriteLine("Here 1");
            string s = Dog.Motto;
            Console.WriteLine("Here 2");

The output is (static constructor called before accessing static data):

#294 – Make All Constructors Private to Prevent Object Creation

If you want to prevent code external to a class from creating instances of that class, you can make all of the constructors of the class private.

In the following example, we have a single Dog constructor, which is private.

        private Dog(string name, int age)
        {
            Name = name;
            Age = age;
        }

Because the constructor is private, code outside the Dog class cannot create a new instance of a Dog.

But we can have a static method in the Dog class that can create instances.  Because the code is defined inside the Dog class, it has access to the private constructor.

public class Dog
{
        // code omitted

        public static Dog MakeADog()
        {
            // Use private constructor
            Dog nextDog = new Dog(nameList[nextDogIndex], ageList[nextDogIndex]);

            nextDogIndex = (nextDogIndex == (nameList.Length - 1)) ? 0 : nextDogIndex++;

            return nextDog;
        }

Now if we want a new Dog instance, we can call the MakeADog method.

#292 – A Static Constructor Initializes Static Data

In the same way that you can define instance constructors to initialize instance data in a class, you can define a static constructor to initialize any static data in the class.

A static constructor is defined using the static keyword and the name of the class.  The constructor takes no arguments and you can only define one static constructor.  You do not declare a static constructor as either public or private.

        public static string Motto { get; set; }
        public static int NumDogs { get; private set; }

        static Dog()
        {
            Motto = "We're like wolves.  Only friendlier.";
            NumDogs = 0;
        }

You cannot dictate when a static constructor will be called and you can’t call it directly.  The compiler guarantees that it will be called automatically before you create any instances of your class or access any static data.

#287 – You Don’t Have to Define a Constructor

It’s not mandatory for a user-defined class to define a constructor.  If one is not defined, the compiler will automatically generate a constructor. This internal constructor will just call the constructor of the class’ base class.  (E.g. The constructor in System.Object).

You can use the IL DASM tool to inspect the code for your class and see this automatically generated constructor.

For example, let’s say that we have a Dog class that does not define a constructor.  Below is an image of the IL DASM, showing the metadata for the Dog class.  Note that it shows the following elements in the class:

  • Age and Name properties
  • get and set accessors for the properties
  • Backing variables for the properties
  • A Bark method
  • A method called .ctor–this is the automatically-generated constructor

This constructor just calls the System.Object constructor:

#286 – A Constructor is Called When an Instance of a Class Is Created

A constructor is a method that is called when a new instance of a class is created.  (Technically, this definition applies to instance constructors–I’ll cover static constructors later).

A constructor normally allows a class to initialize its data members, as part of the process of creating a new instance.

A constructor is defined by using the class’ name as the method name.  The simplest form of constructor, known as the default constructor, takes no parameters.

    public class Dog
    {
        public string Name { get; set; }
        public int Age { get; set; }

        // Constructor, called when we create a new Dog
        public Dog()
        {
            // Set a default name
            Name = "Pooch";
        }
    }

The constructor in the above example is called when we create a new instance of a Dog, using the new operator.

            Dog someDog = new Dog();

            Console.WriteLine(someDog.Name);       // Pooch

#37 – All Value Types Have a Default Constructor

All built-in value types in C# support a default (parameterless) constructor using the new keyword.  The default constructor allows you to instantiate an object such that it takes on a default value.

You’d normally instantiate one of the built-in types by giving  the associated variable a value.  But it’s also possible to use the new keyword to cause the variable to take on a default value.

 int i;          // Not instantiated yet
 int n1 = 12;    // Instanatiated, w/value of 12
 int n2 = new int();   // Instantiated, w/default value

The default values for the built-in value types are:

  • bool type = false
  • Numeric types (e.g. int, float) = 0 or 0.0
  • char type = single empty character
  • DateTime type = 1/1/0001 12:00:00 AM
Follow

Get every new post delivered to your Inbox.

Join 43 other followers