#1,220 – C# 6.0 – Defining a Parameterless Constructor for a struct

In C# 5.0, every struct had a default parameterless constructor that you couldn’t override.  Using the new operator invoked this constructor and all members of the struct were assigned default values.

    public struct MyPoint
    {
        public double X;
        public double Y;
    }

    class Program
    {
        static void Main(string[] args)
        {
            MyPoint pt = new MyPoint();      // default values for X, Y (0.0)
            Console.WriteLine("{0}, {1}", pt.X, pt.Y);
        }
    }

1220-002

In C# 6.0, you can explicitly define a parameterless constructor for a struct, giving non-default values to the members of the struct.

        public struct MyPoint
        {
            public double X;
            public double Y;

            public MyPoint()
            {
                X = 100.0;
                Y = 100.0;
            }
        }

        static void Main(string[] args)
        {
            MyPoint pt = new MyPoint();      // 100.0, 100.0
            Console.WriteLine("{0}, {1}", pt.X, pt.Y);
        }

1220-001

Advertisements

#1,029 – How to Define a Constructor in a Generic Type

When you define a generic type, you include one or more type parameters in the declaration of the type, indicating the type of the type arguments that you specify when constructing an instance of the type.

As with other types, you can define one or more constructors in a generic type.  The constructor uses the name of the type, but without the associated type parameters.  You can, however, have constructors that accept parameters whose type is one of the type parameters.

In the example below, the second constructor makes use of the T type parameter.

    public class PileOf<T>
    {
        private List<T> thePile;

        public PileOf()
        {
            thePile = new List<T>();
        }

        public PileOf(T firstThingInPile)
        {
            thePile = new List<T>();
            thePile.Add(firstThingInPile);
        }

        public void AddThing(T thing)
        {
            thePile.Add(thing);
        }
    }

We can then use this type as follows:

            PileOf<Dog> intPile = new PileOf<Dog>(new Dog("Bowser"));
            intPile.AddThing(new Dog("Fido"));

#1, 023 – Fields Are Initialized Before Execution of Constructors

When you declare a field in a class and initialize the field when it is declared, the initialization of the field will happen when an instance of the class is created, but before the constructor is invoked.  All fields are initialized before the constructor executes, in the order in which they are declared.

Assume that we have a Dog class defined as follows:

    public class Dog
    {
        public string Sound = "Woof";
        public Cat Friend = new Cat("Garfield");
        public string Name { get; set; }

        public Dog(string name)
        {
            Console.WriteLine("Dog constructor for {0}, Sound is {1}", name, Sound);
            Name = name;
        }
    }

When we create an instance of a Dog, the Sound and Friend fields are initialized before the Dog constructor is invoked.

            Dog d = new Dog("Kirby");

1023-001

#874 – An Exception Can Be Thrown from a Constructor

You can throw an exception from a constructor.  For example, in the code below, the Dog constructor throws an exception if an invalid age parameter is passed in.

        // Dog constructor
        public Dog(string name, int age)
        {
            if ((age < 1) || (age > 29))
                throw new ArgumentException("Invalid dog age");

            Name = name;
            Age = age;
        }

The code below catches an exception that happens during construction. Note that the Dog object was never instantiated, so the reference is still null.

            Dog myNewDog = null;

            try
            {
                myNewDog = new Dog("Methuselah", 43);
                Console.WriteLine("We just created an old dog");
            }
            catch (Exception xx)
            {
                Console.WriteLine(
                    string.Format("Caught in Main(): {0}",
                                  xx.Message));
                bool nullDog = (myNewDog == null);
                Console.WriteLine(
                    string.Format("myNewDog is null = {0}", nullDog));
            }

874-001

#824 – A Copy Constructor Makes a Copy of an Existing Object

A copy constructor is a constructor that you can define which initializes an instance of a class based on a different instance of the same class.

In the example below, we define a copy constructor for Dog.  The constructor creates a new instance of a Dog based on an existing instance.

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

        // Constructor that takes individual property values
        public Dog(string name, int age)
        {
            Name = name;
            Age = age;
        }

        // Copy constructor
        public Dog(Dog otherDog)
        {
            Name = otherDog.Name;
            Age = otherDog.Age;
        }
    }

Example of using the copy constructor:

            // Create a dog
            Dog myDog = new Dog("Kirby", 15);

            // Create a copy of Kirby
            Dog other = new Dog(myDog);

824-001

#820 – A Protected Constructor Allows a Subclass to Create Instances

You can declare a constructor as private to prevent client code from directly instantiating an object.  But then you can no longer subclass the class, because the derived class won’t have access to the constructor.

If you want private constructor semantics, but still be able to create a subclass, you can make a constructor protected.  Other code won’t be able to construct instances of the base class, but your subclass will be able to call the constructor.

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

        protected Dog()
        {
            Console.WriteLine("Constructing Dog");
        }
    }

 

    public class Terrier : Dog
    {
        public double FeistyFactor { get; set; }

        // Implicitly invokes default constructor in base class
        public Terrier(string name, int age, double feistyFactor)
        {
            Console.WriteLine("Constructing Terrier");
            Name = name;
            Age = age;
            FeistyFactor = feistyFactor;
        }
    }

820-001

#819 – A Private Constructor May Prevent Inheritance

You can make a constructor private to restrict creation of an instance of the class only to code within the class.

If all constructors in a class are private, this means that a derived class is also prevented from calling a constructor.  Because the derived class must be able to call some constructor on the parent class, this will effectively prevent the creation of any derived class.

Assume that a Dog class defines a single constructor and makes it private.  In the code shown below, the Terrier class defines a constructor, which would implicitly call the default constructor in the base class.  Because that constructor is private, we get a compiler error and can’t create the Terrier class.

    public class Terrier : Dog
    {
        public double FeistyFactor { get; set; }

        public Terrier(string name, int age, double feistyFactor)
        {
            Name = name;
            Age = age;
            FeistyFactor = feistyFactor;
        }
    }

819-001