What puzzled me: how can it be used in a derived class as "private"? What does this mean ("Default Name")? ** How does an object get a "Default Name" as its name?
You are right to be puzzled!
This sample code does not call the default constructor at all - and since it is private, nothing else can call it without using reflection (not even a derived class, it must be at least protected for the derived class to be called - or the derived class must be nested base class).
In the sample code, the object does not receive the "Default Name" value as its value.
So this is a typo or mistake in the book.
The correct solution for describing a book:
- Omit the default constructor in general.
- Initialize
Name in the field. This ensures that it cannot be initialized, no matter what other constructors are written in this or any derived class.
Same:
class MyClass { public readonly string Name = "Default Name"; private int intVal; public int Val { get { return intVal; } set { if (0 <= value && value <= 10) intVal = value; else throw (new ArgumentOutOfRangeException("Val", value, "Val must be assigned a value between 0 and 10.")); } } public override string ToString() { return "Name: " + Name + "\nVal: " + Val; } public MyClass(string newName) { Name = newName; intVal = 0; } }
Note that it is often useful to declare a private default constructor that is called by other constructors, but the declaration class should really use it.
Also note that if you declare a non-default constructor in the base class and do not declare the default constructor at all, any derived class must call one of the existing base class constructors.
For example, if the class definition above is specified, then both of the following class declarations will cause a compilation error MyClass' does not contain a constructor that takes 0 arguments :
class MyDerivedClass1: MyClass { public MyDerivedClass1()
To fix the error, MyDerivedClass must call the existing constructor:
class MyDerivedClass: MyClass { public MyDerivedClass(): base("My new name") { } }
So what is a private constructor
A pretty typical use is to put common initialization code in the default constructor. Sometimes, however, you do not want the caller to be able to create a type by default β in this case, you can make the default constructor private.
That way, you can still use the default constructor for normal initialization, but you forbid using code outside the class, for example:
class Test { public readonly int IntValue; public readonly string StringValue; private Test() {
Often you can use the private init() method to perform general initialization, but if you initialize the readonly field, you must use the constructor to do this. In this case, instead of the init() method, a private constructor should be used.
Another use of a private default constructor is to prevent any type instance at all (you simply declare your own default constructor and no other constructors at all).
In .Net 1.x, this was the only way to do this, but in subsequent versions of .Net, static classes were introduced that in most cases removed the need to use a private constructor for this type.
You can also declare a private constructor to force the static factory method to instantiate the type.
Just for completeness, here's a far-fetched example demonstrating how a private constructor can be called from a nested derived class:
class OuterClass { public readonly string Value; private OuterClass(): this("Default Value") { } public OuterClass(string value) { Value = value; } public OuterClass GetInnerClass() { return new InnerClass(); } private class InnerClass: OuterClass { } }
With this class definition, the following code will print "Default":
OuterClass test = new OuterClass("Test"); Console.WriteLine(test.GetInnerClass().Value);
Personally, I never had to write a nested class that derives from its containing class, but this is possible if you need to do this for some reason.