How does an empty constructor work?

6

Definition: Creating an empty constructor If the attributes are not set, they will be set to the default type , example: int default value is zero. >

Context: I use a structure that returns entities from the database and when the object is not found it returns null , so I used that wildcard of the constructor, for when it 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 besides that if there are other uses of this technique? Is there 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();
}
    
asked by Laerte 24.04.2014 в 23:29

4 answers

4

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

If you declare a constructor in which the members are modified, the modification occurs after constructing the object. Think about it: you necessarily need an object already built to operate on it. I think the cause of the confusion is just the name "constructor", since it will act on an object already built.

The process is actually the following:

Object does not exist - > builder request - > Allocation - > construction - > Your constructor runs on the newly constructed object - > control back to your program

Explaining otherwise: when the program encounters an instruction of type:

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

Realize that not necessarily a constructor needs to change the members of the object it operates on. It can trigger 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.

    
24.04.2014 / 23:40
3

When no constructor is specified in a class, C # will automatically compile a public parameterless constructor, which will leave the fields all with the default values of each type. The default values for structs can vary from type to type, and classes are always null. The default values are always the values corresponding to the zeroed memory, that is, filled with bits 0.

To initialize the new instance

You can manually encode a parameterless constructor in order to change the default C # behavior, which is usually done to fill in the values of the fields with values that make sense, or else 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 were 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 default parameters

Suppose a base class BaseClass only has constructors with parameters. When inheriting from this class, you will be required to provide a constructor for the class, since C # will not generate one automatically. Therefore, you will have to code a constructor, either 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 so that you can change its visibility, for example, to make it a protected constructor:

class MyClass
{
    protected MyClass()
    {
    }
}

then you can only access the constructor like this:

class MyClass2 : MyClass
{
    public MyClass2()
        : base() // chamando o construtor de MyClass
    {
    }
}

Some encoding standards depend on a constructor with reduced visibility:

  • Singleton: If the constructor were publicly visible, or even could be seen by heirs, multiple instances of the class could be created.
  • Factory: If the constructor is visible, then other creative 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 builders. The instance constructor has far fewer guarantees than the static constructor, and the purpose is different.

There are also differences between instance and structure builders. It is not possible to create a structure constructor without parameters, and the structure constructor must fill all the fields of the structure.

  • static constructor: initializes static members, with the assurance that the constructor will be called only once (it is thread safe) before any use of the type. For generic types, the constructor is called for each type that is generated using the generic parameters. Also, if the static constructor throws an exception once, the exception is stored and relaunched every time the user type it again.

  • Instance constructor: Initializes the members of an instance of the class. It is not thread safe, as well as providing no particular warranty on reordering of readings and writes, which may cause a newly created object created on one thread is observed on another maliciously initialized thread .

    It is necessary to instantiate before using any field of an object of class.

  • structure constructor: must initialize all members of the structure, and can not fall in the case of the question about constructors without parameters, because C # does not allow to define such a constructor. When using the default constructor of the structure, it is the same as using the defaut value of type:

    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;
    
24.04.2014 в 23:35
1
  

How does the program make this association that empty constructor means to set all attributes to default values?

This is not true, the empty constructor does not mean that the attributes of the classes will be initialized with default values, that is to say only that the object can be created without changing its attributes.

Every attribute that belongs to the class has default values regardless of how its constructor is specified.

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

    
24.04.2014 в 23:39
0

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

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

To start the value of a private field in your class, you 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 ...
}
    
24.04.2014 в 23:33