Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

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.

share|improve this question
3  
This looks perfectly sensible to me. –  Robert Harvey Aug 1 '13 at 0:42
    
One thing worth mentioning, most generic collection type classes implement IEnumerable. This interface is the driving force behind LINQ to Objects and is extremely powerful for manipulating sequences of things. –  mortalapeman Aug 1 '13 at 1:24
    
As additional info, use IEnumerable instead of IList to make it immutable. Moreover, IEnumerable support input (implicit cast) from array of object and other collection such as List. –  Fendy Aug 1 '13 at 3:04

2 Answers 2

up vote 8 down vote accepted

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.

share|improve this answer
    
I'm not sure. I came here to post the same answer. I +1ed you. –  MetaFight Aug 1 '13 at 7:46
1  
Keep in mind that calling ToList() on an IEnumerable<T> will enumerate the object. (this has some impact on performance) If you need LINQ often, it may be better not to use an IEnumerable<T>, but directly use a List<T> –  Timothy Groote Aug 1 '13 at 7:55
3  
@Stephen Why should List<T> be so strictly avoided outside of local variables? –  Philipp Aug 1 '13 at 8:05
2  
@TimothyGroote: Why? List<T> is not lazy, and the Linq methods called on a List<T> object operate on the underlying IEnumerable anyway, so what difference does it make? Seems like IQueryable might be a better choice, if Linq is needed downstream. –  Robert Harvey Aug 1 '13 at 16:28
2  
One gotcha: An IEnumerable can only safely be enumerated once, and may be expensive to enumerate multiple times even when safe to do so. Thus, I usually avoid IEnumerable fields and members. A class could use a ReadOnlyCollection<T> (or the corresponding interface), if you need to go a step further and promise not to modify your collection. –  Brian Aug 12 '13 at 19:22

The difference between ICollection and Set is that ICollection represents an arbitrary collection of items, while Set and ISet represent mathematical sets, e.g. no duplicate items and items have no defined order. .NET's version has more methods, because those operations are expected from mathematical sets. The reason why IDictionary doesn't implement ISet is most probably because then KeyValuePair<Key,Value> must have defined proper equality, which would transitively require Value to have defined equality. But IDictionary only requires equality to be defined for Key and not Value.

Also you should learn about the Difference between List(T) and Collection(T) in .NET

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.