0

I need to know what is the best and efficent way to instance the new List on a property and why?

Option one

public class ObjectA
{
   public List<ObjectB> MyList { get; set; } = new List<ObjectB>();
}

Option two

public class ObjectA
{
    public List<ObjectB> MyList { get; set; } 

    public ObjectA()
    {
        this.MyList = new List<ObjectB>();
    }
}
  • Similar with lot of explanation :https://stackoverflow.com/questions/24551/initialize-class-fields-in-constructor-or-at-declaration – Bharat Jul 23 '21 at 00:59
  • Suggested reading: **[Guidelines for Collections](https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/guidelines-for-collections)** – Ňɏssa Pøngjǣrdenlarp Jul 23 '21 at 01:08
  • I think it's not the duplicated of initialization of values, rather it's about the location of field object instantiation – Bharat Jul 23 '21 at 02:25

1 Answers1

0

Though there are multiple explanations, I will attempt based on my understanding using the IL code of various scenarios.

  1. Instantiate the list in the constructor

In this case, when the object is constructed by this constructor it would first make a call to instance void [System.Runtime]System.Object::.ctor() and then construct the list

public class ObjectA
{
    public List<string> MyList { get; set; }
    public ObjectA()
    {
        this.MyList = new List<string>();
    }
}

enter image description here

  1. Instantiate the list at the declaration

In this case, when the object is constructed it would first construct the list and then make a call to the default constructor instance void [System.Runtime]System.Object::.ctor() and then initialize the list

public class ObjectA
{
    public List<string> MyList { get; set; } = new List<string>();
}

enter image description here

  1. Instantiate the list at the declaration but the class has one constructor

In this case, compiler has injected the code for the list instantiation in the constructor

public class ObjectA
{
    public List<string> MyList { get; set; } = new List<string>();
    public ObjectA()
    {

    }
}

enter image description here

  1. Instantiate the list at the declaration, and create the class with different constructor

In this case we can see the compiler has injected the code for the list instantiation in the new constructor too

public class ObjectA
{
    public List<string> MyList { get; set; } = new List<string>();
    public ObjectA(int x)
    {

    }
}
public class ObjectB:ObjectA
{
    public ObjectB(int x):base(x)
    {
        
    }
}

enter image description here

  1. Instantiate the list at the declaration, calss has two constructors and a derived class

In this case, the compiler injected the list instantiation code in both the constructors. This would not happen in the case where we instantiate the list in the constructor

public class ObjectA
{
    public List<string> MyList { get; set; } = new List<string>();
    public ObjectA()
    {

    }
    public ObjectA(int x)
    {

    }
}
public class ObjectB:ObjectA
{
    public ObjectB(int x):base(x)
    {
        
    }
}

enter image description here

To summarise, In case of lists or similar objects if you have multiple constructors. It's developer's responsibility to ensure all required objects are initialized before the use. The complexity increases when this class gets derived. If we follow the clean code practices, smaller classes I would go with initiaize at declaration. But if the field objects are going to be big, doing some work at their construction, I would initialize them when required (This requires safety)

Bharat
  • 1,192
  • 7
  • 14