Collections

IEnumerable vs IList vs IReadOnlyList

  • For inputs use the most restrictive collection type possible, for example IReadOnlyCollection / IReadOnlyList / IEnumerable as inputs to methods when the inputs should be immutable.
  • For outputs, if passing ownership of the returned container to the owner, prefer IList over IEnumerable. If not transferring ownership, prefer the most restrictive option.

Arrays vs Lists

  • In general, prefer List<> over arrays for public variables, properties, and return types (keeping in mind the guidance on IList / IEnumerable / IReadOnlyList above).
  • DO prefer List<> when the size of the container can change.
  • DO prefer arrays when the size of the container is fixed and known at construction time.
  • DO prefer array for multidimensional arrays.
  • Note:
    • Array and List<> both represent linear, contiguous containers.
    • Similar to C++ arrays vs std::vector, arrays are of fixed capacity, whereas List<> can be added to.

General Tips

  • ✅ While returning collection return empty collection instead of returning null when you have no data to return.

  • DO always check Any() operator instead of checking count i.e. collection.Count > 0 and checking of null.

  • DO use IList<T>, IEnumrable<T>, ICollection<T> instead of concrete classes e.g. using List<>.

  • DO use foreach instead of for loop while traversing.

    The foreach statement is a variation of do, while or for loops. It actually generates the best iteration code for any collection you have.

    When you are using collections, always prefer to use the foreach loop as the C# compiler generates the best iteration code for your particular collection. Have a look into the following implementation:

    foreach(var item in DocumentCollection)
    {
        // ...
    }
    

    Here, if your DocumentCollection is an Array type, the C# compiler will generate the following code for you:

    for(int index = 0; index < DocumentCollection.Length; index++)
    {
        // ...
    }
    

    In future, if you change your collection type to ArrayList instead of Array, the foreach loop will still compile and work properly. In this case, it will generate the following code:

    for(int index = 0; index < DocumentCollection.Count; index++)
    {
        // your code
    }
    

    Just check the for condition. You will see a little difference there. Array has Length property and hence it generated code which calls the Length.

    But in case of ArrayList, it replaced the Length with Count, as ArrayList has Count which does the same thing. In other scenario, if your collection type implements IEnumerator, it will generate a different code for you. Let’s see the code:

    IEnumerator enumerator = DocumentCollection.GetEnumerator();
    
    while(enumerator.MoveNext())
    {
        // your code
    }
    

    Hence, you don’t have to think which loop to use. The compiler is responsible for that and it will choose the best loop for you.

    One more advantage of foreach loop is while looping through the Single Dimensional or Multi Dimensional array. In case of Multi Dimensional array, you don’t have to write multi line for statements. Hence, it will reduce the code you have to write. The compiler internally will generate that code. Thus, increases your productivity.

Learn More