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 inforeach
loops. It also contains a number of quite useful extension methods, which allow you to do anything from convert it to a list by callingToList()
, filtering results by callingWhere(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 theIList<T>
interface.