How does an empty constructor work?

Asked

Viewed 6,284 times

6

Definition: Creating an empty constructor attributes if not set will be set to the default value of guy, example: int default value is zero.

Context: Use a structure that returns entities from the database and when the object is not found it returns null, so I used this joker from the constructor, for when this happens to instantiate the object with the empty constructor, I had to use polymorphism in the constructor because there was already a constructor, example: var pessoa = PessoaController.Obter(id) ?? new Pessoa();

Doubt: How does this work (How does the program make this association that empty constructor means to set all attributes to default values?). Is it used when classes have attributes that are other classes than this case there are other uses of this technique? There is another way to implement this without using a constructor?

public class Pessoa
{
    public string Nome { get; set; }
    public DateTime DataNascimento { get; set; }
    public Pessoa() { }
    public Pessoa(string nome, DateTime dtNasc, int cpf)
    {
        Nome = nome;
        DataNascimento = dtNasc;
        CPF = cpf;
    }
}

public class Faculdade
{
    public Pessoa Mantenedor { get; set; }
    public List<Aluno> Alunos { get; set;}
    public List<Disciplina> Disciplinas { get; set; }

    public Faculdade()
    {
        Mantenedor = new Pessoa();
        Alunos = new List<Aluno>();
        Disciplinas = new List<Disciplina>();
    }
}

public class Aluno
{
    public string Nome { get; set; }
    public int RM { get; set; }
    public bool Sexo { get; set; }          
    public Aluno() { }
}

public class Disciplina
{
    public string Nome { get; set; }
    public Disciplina() { }
}

private static void Main(string[] args)
{
    Faculdade USP = new Faculdade();
    Console.Write(USP.Mantenedor.Nome); // Retorna vazio
    Console.ReadKey();
}
  • 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 that entity is not null.

  • 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.

4 answers

4


Every object is initially constructed with default values for all its members. This is a null reference for all members whose types are by reference, and the standard value of the type for all other members. In this case, the default value depends on the implementation of the type. In general, it is equivalent to zero for numeric types (short, int, long, float, double, uint etc.), the lowest usable date for DateTime, a zero time interval for TimeSPan etc..

If you declare a constructor in which members are modified, the modification occurs after the construction of the object. Think about it: you necessarily need an object already built to be able to operate on it. I believe that the cause of the confusion is precisely the name "builder", since it will act on an already built object.

The process is actually as follows:

object does not exist -> request to the constructor -> allocation -> building -> your constructor runs on the newly built object -> control back to your program

Explaining otherwise: when the program comes across an instruction of the type:

var f = new Foo(bar);
  • The program creates an object of type Foo;
  • Then executes the manufacturer used (in this case, the one that receives the variable bar) on the object that has just been created;
  • Finally, the application makes the reference f "point" to the created object.

Note that a constructor does not necessarily need to change the members of the object on which it operates. It can fire an event, perform operations on other objects etc.

Declaring an empty constructor in general has no meaning unless you use a visibility modifier (i.e.: private or internal) to control the contexts in which your object can be created.

3

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;
    

1

How the program makes this association which empty constructor means to set all attributes to default values?

This is not true, the empty constructor does not mean that class attributes will be initialized with default values, it just means that the object can be created without changing its attributes.

Every attribute belonging to the class has standard values independent of how its constructor is specified.

However, the same does not apply to attributes that belong to methods, because in this case there is a requirement to be initialized explicitly. If you try to use an attribute of a method without initializing it you will get a build error.

0

If the constructor of your class is empty, there is no need to specify it.

Classes that do not have constructors at first are objects that do not require mandatory values to exist when they are instantiated.

to start the value of a private field in its class, Voce can do it without needing a constructor:

public class Faculdade
{
    private Pessoa mantenedor_ = new Pessoa();
    private List<Aluno> alunos_ = new List<Aluno>();
    private List<Disciplina> disciplinas_ = new List<Disciplina>();

    public // propriedades ...
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.