CodeRush code issues specific to constructors

September 29th, 2011

A constructor is a special class member that is executed when a new object is created. There are two types of constructors: instance constructors and static constructors. Instance constructors are used to create and initialize instances of classes or structures. A static constructor is used to initialize a class itself. A static constructor is called automatically to initialize the class before the first instance is created or any static members are invoked.

All instance constructors implicitly include an invocation of another instance constructor immediately before the constructor-body if no constructor initializer is specified. There are two types of constructor initializers: a form base(), which calls a base class constructor and a form this(), which calls another constructor in the current class. There must always be a chain of constructors which invoke other constructors all the way up the class hierarchy. If an instance constructor has no constructor initializer, a constructor initializer of the form base() is implicitly provided.

DevExpress CodeRush provides several code issues specific for constructors. Most of them are hints (or suggestions) and others are errors. Code issues of an error type help you to avoid mistakes while declaring constructors inside classes or structures. Code issues of a suggestion (hint) type may help you to make your code more efficient and readable.

Here they are:

Constructor cannot call itself

Cause:

As I’ve said earlier, there must be a chain of constructors which invokes other constructors in the current class and/or class hierarchy. It is meaningless for a constructor to call itself, because there is no need to call the same instance initialization code. In fact, it would result in an infinite recursion if permitted. That is why a constructor cannot call itself.

Sample:

How to fix:

Remove the call to the same constructor:

Redundant base constructor call

Cause:

We already know that if no constructor initializer is explicitly specified, then a constructor of the form base() (parameterless) is implicitly provided. There is no need to explicitly specify the parameterless base constructor call. That is why it is redundant and can be safely removed. Removing the redundant base constructor call may improve code readability.

Static constructors cannot have access modifiers

Cause:

Static constructors cannot be called directly, they are called automatically as written previously. That is why you cannot include an access modifier (e.g. public, protected) when defining a static constructor. An access modifier is simply redundant and not allowed by the CSharp language specification, for example. You will see an error code issue inside the code editor when a static constructor has access modifiers.

Sample:

How to fix:

Remove the access modifiers from the static constructor:

Struct cannot contain parameterless constructor

Cause:

Structs can have constructors just like classes. However, constructors and structs behave a bit differently from classes. Structs can have instance constructors with one notable exception – they cannot have a user-defined default parameterless constructor.

Parameterless constructors are not necessary for value types, since the compiler, by default, neither generates a default constructor, nor generates a call to the default constructor, which simply sets the fields of the value type to their default (zero) values. When an instance that has all of its fields zeroed is created, a user can, in some cases, then use this instance without further initialization.

It is important to make sure that the all-zeroed state is a valid initial state for the value types. A default parameterless constructor for a struct could set different values than the all-zeroed state which would be an unexpected behavior. The .NET Framework therefore prohibits default constructors for struct. An error is shown when you have such a constructor.

Sample:

How to fix:

Mark the constructor ‘static’:

Virtual member call in constructor

Cause:

The order in which constructors are called is different from the order in which virtual methods are called. Calling virtual methods during construction will cause the most derived override to be called, even though the most derived constructor has not been completely run yet.

When an object is constructed, the object initializers run in an order from the most derived class to the top base class, and then constructors run in an order from the top base class to the most derived class. Objects being constructed do not change their type during initialization, but start out as the most derived type, with the method table being generated for the most derived type. This means that virtual method calls always run on the most derived type. If you invoke a virtual method in a constructor, and it is not the most derived type in its inheritance hierarchy, then it will be called on a class whose constructor has not been run yet, and therefore may not be in the correct state to have that method called. That is why calling a virtual method can produce unexpected results.