.NET Collections

Do not use collections from System.Collections unless you are maintaining legacy code. They don’t provide type safety and they have poor performance when used with value types.

The collections can be easily grouped in a few categories based on the interfaces they implement. These determine which operations are supported by a collection and consequently in which scenarios can they be used.

The common interface for collections is the ICollection interface. It inherits from the IEnumerable interface which provides the means for iterating through a collection of items. The ICollection interface adds the Count property and methods for modifying the collection:

The authors of the Base Class Library (BCL) believed that these suffice for implementing a simple collection. Three different interfaces extend this base interface in different ways to provide additional functionalities.

  1. Lists
    • The IList interface describes collections with items which can be accessed by their index
  2.  Sets
    • ISet interface describes a set, i.e. a collection of unique items which doesn’t guarantee to preserve their order. it will only add the item to the collection if it’s not already present in it. The return value will indicate if the item was added. The most basic implementation of ISet is the HashSet class. If you want the items in the set to be sorted, you can use SortedSet instead.
  3. Dictionaries
    • IDictionary<tkey, tvalue= » »>  stores key-value pairs instead of standalone values. The indexer allows getting and setting the values based on a key instead of an index:</tkey,></tkey,>.

 

Queue and Stack

The Queue class implements a FIFO (First in, First out) collection. Only a single item in it is directly accessible, i.e. the one that’s in it for the longest time.

The Stack class is similar to Queue, but it implements a LIFO (Last in, First out) collection. The single item that’s directly accessible in this collection is the one that was added the most recently.

Thread safety

The regular generic classes in the Base Class Library have one very important deficiency they are not entirely thread-safe. While most of them support several concurrent readers, the reading operations are still not thread-safe as no concurrent write access is allowed. As soon as the collection has to be modified, any access to it from multiple threads must be synchronized.The simplest approach to implementing such synchronization involves using the lock statement with a common synchronization object but the Base Class Library comes with the ReaderWriterLockSlim class which can be used to implement this specific functionality simpler.

Concurrent collections

The concurrent collections in the System.Collections.Concurrent namespace provide thread-safe implementations of collection interfaces.

Immutable collections

Immutable collections aren’t included in the Base Class Library. To use them, the System.Collections.Immutable NuGet package must be installed in the project. They take a different approach to making collections thread-safe. Instead of using synchronization locks as concurrent collections do, immutable collections can’t be changed after they are created. This automatically makes them safe to use in multi-threaded scenarios since there’s no way for another thread to modify them and make the state inconsistent.

When choosing a collection to use in your code, always start by thinking through which operations you will need to perform on that collection. Based on that, you can select the most appropriate collection interface. Unless you have any other special requirements, go with an implementation from the System. Collections.Generic namespace. If you’re writing a multithreaded application and will need to modify the collection from multiple threads, choose the concurrent implementation of the same interface instead. Consider immutable collections if their behavior and performance match your requirements best.

.NET is now cross-platform

Microsoft is building a new version of .NET, called .NET Core, which is open-source and which will allow us to write cross-platform code (Windows, multiple distributions of Linux and OS X). The goal is to run .NET Core in as many places as possible. In fact, the code is portable and it can be run on different supported platforms: .NET Framework, Mono, Xamarin,  Windows 8, Windows Phone, Universal Windows Platform (UWP). There is a list of multiple implementations based on .NET Standards and it can be found on github.

The design and the architecture of .NET core are modular and its component are all separate entities. This way the developers can choose the libraries and the dependencies that are needed.

We can write code for .NET Core on:

  • cross-platform ASP.NET Web apps using ASP.NET Core 1.0. Until February it was called ASP.NET 5
  • cross-platform console apps
  • cross-platform libraries and frameworks
  • UWP apps (apps that target the family of Windows 10 devices)

.NET has now 2 flavors: NET Core and .NET Framework

First of all, .NET Core is not a subset of .NET Framework. It is a different stack. We will still be able to use the same languages: C#, F#, Visual Basic but we should see .NET Core and .NET Framework as two different stacks that coincide and co-evolve. .NET Core was created so that .NET could be open source and cross-platform.

A big difference between .NET Framework and .NET Core is the way how they are serviced and where they live. As we know, .NET Framework is a Windows component serviced through OS updated while .NET Core is composed of Nuget packages and it can be serviced per-application and through a package manager.

The .NET Framework will continue to be the stack to use when writing application ranging from console applications, rich client (WPF) applications to scalabe web applications.