C# Collection Interfaces – Transitioning from Java

cdata structuresinterfacesjava

In Java, I'm used to declaring collections using the most-abstract interface possible and then constructing them using the concrete implementation that makes sense at the time. It usually looks something like this:

public class MyStuff {
    private Map<String, Address> customerAddresses;
    private List<ToDoItem> tasks;
    private Set<Person> people;

    public MyStuff() {
        customerAddresses = new HashMap<String, Address>();
        tasks = new ArrayList<ToDoItem>();
        people = new HashSet<Person>();
    }
}

This allows me more flexibility to change a collection's implementation later when all I really depend on is the high-level interface (i.e. I need something to store key-value pairs, or something to store ordered data), and it's generally considered a standard "best practice" in Java.

I'm just starting to program in C#, though, and I'm not sure if there's an equivalent practice for C#'s collections hierarchy. Collections in C# differ from collections in Java in several ways: Collection is a concrete type, the ICollection interface exposes similar methods to Java's Set while the ISet interface specifies a lot more features, and the key-set or value-set of a Dictionary is not an ISet, to name a few. Does it make sense to do something like this in C#?

public class MyStuff {
    private IDictionary<String, Address> customerAddresses;
    private IList<ToDoItem> tasks;
    private ISet<Person> people;

    public MyStuff() {
        customerAddresses = new Dictionary<String, Address>();
        tasks = new List<ToDoItem>();
        people = new HashSet<Person>();
    }
}

Or are there different "standard" interfaces and implementations to use for such collections? Should I be using ICollection and Collection in place of either the Set or the List? I'm tempted to use the C# classes and interfaces that "look closest" to the Java ones I'm used to, but I'd rather use the setup that better fits with C# paradigms and standards.

Best Answer

IEnumerable<T> is the interface to use. It is the most basic interface available for collection type objects. IEnumerable<T> is able to be used in foreach loops. It also contains a number of quite useful extension methods, which allow you to do anything from convert it to a list by calling ToList(), filtering results by calling Where(x => { //filtering functionality } and all sorts of other things.

The other interface to use is IDictionary<U, V>, which is the interface to use for dictionaries. ConcurrentDictionary<TKey, TValue> is probably the most useful of the standard concrete dictionary types as it is designed (funnily enough) for concurrency.

Whatever you do, avoid using List<T> outside of local variables.

The other thing to note is that LinkedList<T> does not implement the IList<T> interface.

Related Topic