Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Microsoft Guidelines for Collections: Confused about several parts

I'm looking at Microsoft's Guidelines for Collections and I find a few parts hard to understand:

X DO NOT use ArrayList or List<T> in public APIs. Does this mean that I should avoid returning List<T> altogether, or that I could return it as an IEnumerable/IList, but not explicitly as List<T>?

✓ DO use the least-specialized type possible as a parameter type. Most members taking collections as parameters use the IEnumerable<T> interface. After seeing ReSharper complain about "possible multiple enumeration of IEnumerable", I thought it was a better idea to take (and return) ICollection<T> when I was expecting a pre-computed, finite collection of objects (i.e. not a lazy stream). Isn't that the case?

✓ DO use Collection<T> or a subclass of Collection<T> for properties or return values representing read/write collections. Why not use ICollection<T>? I thought interfaces were preferable to concrete classes.

like image 676
lfk Avatar asked May 10 '17 01:05

lfk


People also ask

How many types of collections are there in C#?

Collections in C# are classified into two types - Generic collections and non-generic collections.


1 Answers

These guidleines exist to promote designing methods that are flexible in what they accept as parameters and in what they return as return types.

If you return a List<T> from a method, that method can never return anything that's not a List<T>. This may be fine in some scenarios but not so in others. For example, consider a method that returns a collection of users that logged in during a certain period. If this method returns just a List<T>, it has to acquire and return all users in a single pass because those are the semantics of List: you get all items with a total count as soon as the method returns. This may be a problem, if the number of users is several tens of thousands - it may take a long time to get all the records and they may take up a lot of memory.

If this method would return an IEnumerable<T>, there's no promise of a count or getting all items at once - the caller can iterate through the collection of items but not get all items in a single go. This allows the called method to return an object (implementing IEnumerable<T>) that collects the data in sevaral small batches and returns them one by one, as requested.

Also, many different collection types implement IEnumerable<T>, so another implementation of this method may actually decide to return a list instance, cast to IEnumerable<T>. The calling method won't know or care, since all it expects is an IEnumerable<T>. This is not the case with a hardcoded list type - it cannot be exchanged for anything else because it's already as concrete as possible.

In general, an generic collection interface will be the most flexible input parameter / return type for any method - an interface will allow you to implement it in a number of ways, mock it out, etc. so you have a lot of flexibility in controlling what gets passed or gets returned. An interface also doesn't (necessarily) have semantic limitations that may become inconvenient as a product evolves.

As for the first advice, ArrayList is an awful type that shouldn't ever be used after .NET 2.0, since the generic types are far better in every way possible.

like image 169
xxbbcc Avatar answered Jan 01 '23 19:01

xxbbcc