Why the parameterless constructor is called without "new" keyword

Viewed 27

I am doing a little .NET application to get use to it but I struggle to understand something. When I pass through the following line of code the parameterless constructor of my Historique class is called.

public void AjouteEvent(int societeId, Evenement evnmt)
{
   Historique histo = _db.Historiques.Where(h => h.ID ==societeId).FirstOrDefault(); // Called here
   histo.Evenements.Add(evnmt);
   _db.SaveChanges();
}

With the following _db object :

        private BddContext _db;
        public Dal()
        {
            _db = new BddContext();
        }

The Historique class :

public class Historique
    {
        [ForeignKey("Societe")]
        public int ID { get; set; }
        public Societe Societe { get; set; }
        public List<Evenement> Evenements { get; set; }
        public Historique()
        {
            Evenements = new List<Evenement>();
            Evenements.Add(new Evenement());
        }
    }

And the Evenement class :

public class Evenement
    {
        public int ID { get; set; }
        public DateTime DateCreation { get; set; } = DateTime.Now;
        [Display(Name = "Date limite"), Required(ErrorMessage = "Veuillez préciser une date limite pour terminer l'évènement.")]
        public DateTime DateLimite { get; set; } = DateTime.Now;
        public string Type { get; set; } = "Création";
        public bool Actif { get; set; } = true;

        public int HistoriqueId { get; set; }
        public Historique Historique { get; set; }
        public override string ToString()
        {
            StringBuilder sb = new StringBuilder(this.Type);
            sb.Append($" / {this.Actif}");
            return sb.ToString();
        }
    }

Thanks for your answers :) !

1 Answers

The answer is fairly straight forward.

When the object is initialised (retrieved from the database), the class is "constructed" using the default constructor. In this case, that would be your paramaterless constructor.

If you are expecting the Historique.Evenements property to have a value being returned from the database you could try this instead ...

public class Historique
{
    [ForeignKey("Societe")]
    public int ID { get; set; }
    public Societe Societe { get; set; }
    public List<Evenement> Evenements { get; set; }
    
    public Historique()
    {
        if (this.Evenements == null) {
            this.Evenements = new List<Evenement>();
            this.Evenements.Add(new Evenement());
        }
    }
}

This would only assign a value if Evenements is null.


Alternatively, if you are only using the constructor to set a default value for Evenements you could do this instead ...

public class Historique
{
    public int ID { get; set; }
    public Societe Societe { get; set; }
    public List<Evenement> Evenements { get; set; } = new List<Evenement>() { new Evenement() };
}

In this case, the class doesn't need a constructor and when the new object is created during the firstOrDefault method, the property is overwritten by whatever comes out of the database.

If the property is never assigned to, then the default property value persists.

Related