When no constructor is specified in a class, C# will automatically compile a constructor with no public parameters, which will leave all fields with the default values of each type. The default values for structs can vary from type to type, and for classes it is always null. The default values are always the values corresponding to zero memory, that is, filled with bits 0.
To initialize the new instance
You can encode a constructor without parameters manually in order to change the default behavior of C#, which is usually done to fill the values of the fields with values that make sense, or else that are more appropriate for an object being instantiated. This can also be done with field initializers, however, the code compiled by C# is as if the initialization was done inside the constructor itself:
private int field;
private string fieldStr;
public MyClass()
{
this.field = 10;
this.fieldStr = "xpto";
}
is exactly the same as:
private int field = 10;
private string fieldStr;
public MyClass()
{
this.fieldStr = "xpto";
}
To call another constructor, passing standard parameters
Suppose a basic class BaseClass
only have constructors with parameters. By inheriting this class, you will be required to provide a constructor for the class, as C# will not automatically generate one. Therefore, you will need to encode a constructor, whether with or without parameters:
class MyClass : BaseClass
{
protected MyClass2()
: base("param") // a base só tem construtores com parâmetros
{
}
}
To change visibility
Another technique is to define a default constructor just to be able to change the visibility of it, for example, to make it a protected constructor:
class MyClass
{
protected MyClass()
{
}
}
then you can only access the constructor:
class MyClass2 : MyClass
{
public MyClass2()
: base() // chamando o construtor de MyClass
{
}
}
Some coding standards depend on a manufacturer with reduced visibility:
Singleton: if the constructor were publicly visible, or even could be seen by heirs, could end up being created multiple instances of the class.
Factory: if the constructor is visible, then other creation streams other than the object factory can be taken.
Instance, structure and static construction
Do not confuse instance constructor with static constructor. There are differences between these constructors. The instance constructor has far fewer guarantees than the static one, and the purpose is different.
There are also differences between instance and structure constructors. It is not possible to create a structure constructor without parameters, and the structure constructor must fill in all fields of the structure.
static builder: initializes static members, with the assurance that the constructor will be called only once (it’s thread-safe), before any use of the type. For generic types, the constructor is called for each type that is generated using generic parameters. Also, if the static constructor throws an exception once, the exception is stored and relaunched every time the type is used again.
instance builder: initializes members of a class instance. It is not thread-safe, apart from providing no particular warranty on re-ordering readings and writing, which can cause a newly created object in a thread is observed in another ill-initialized thread.
It is necessary to instantiate before using any field of a class object.
structure builder: should initialize all members of the structure, not being able to fall in the case of the question that talks about constructors without parameters, because C# does not allow defining such constructor. When using the default structure constructor, it is the same as using the type defaut value:
new MinhaStruct() <==> default(MinhaStruct)
It is not necessary to call the struct constructor before setting the fields if they are public:
TesteStruct t;
t.valor = 10;
It is perfectly valid to use the coalescence operator in this way. Usually I use the same code for the Create and Update actions, so when consulting the DB by the object ID, the return is null, so it means a new one is being created... hence I can have an object this way for sure:
var entity = db.Entidade.SingleOrDefault(x => x.Id == id) ?? new Entidade();
. After that line it is certain thatentity
is not null.– Miguel Angelo
One cool thing about C# 6 is that properties can now have an initializer:
public Pessoa Mantenedor { get; set; } = new Pessoa();
And with the new Primary Constructor feature, it’s even easier to initialize an entire class.– Maniero