Tuesday, September 20, 2011

Microsoft Source Analysis for C#

Unless you are already used to (and we hardly do), one of the hardest things when writing code is to maintain it well documented and well formatted to everyone (even to ourselves) understand what is writing.

Computers cannot review our source code, yet! Thinking on that, a Microsoft employee developed a tool called StyleCop, that, although not used by everyone within the company, has greatly helped lots of teams to maintain their code well organized.

Here you can find the history of the tool and a short explanation on why some Microsoft employees do not follow the (about) 200 rules established by StyleCop.

The tool integrates quite well with Visual Studio allowing different configurations for each project. Downloading the SDK allows you to customize it and even write your own rules. There is also a plugin for StyleCop called StyleCop+ with lots of other rules that can be used to standardize the source code of your project.

Tuesday, September 6, 2011

List or IList: that is the question

On a day during a conversation at work, a question arises: Why do so many developers always refer to List<T> instead of IList<T> in C#? But a convincing answer to this question did not appear. Thus the principle to depend on abstractions and not on concrete implementations was being despised.

Apparently it was not the first time that this question appears. And it is possible to notice that most developers using List<T> instead of IList<T> had been Java programmers one day. Is this the reason?

In C# it is common to use the letter "I" at the beginning of interface names. People who have programmed in Java might be confused since List represents an interface (in Java) while LinkedList and Stack are examples of implementations. It is also important to note that in C#, LiskedList<T>, Queue<T> and Stack<T> do not implement IList<T>, because they do not provide access by index.

It became necessary to understand the generic class List<T>, and the interfaces that it implements (IEnumerable<t>, ICollection<T>, IList<T>, IEnumerable, ICollection and IList). Thus, such interfaces could be used as a reference instead of the concrete class.

With that understanding about interfaces in mind, it was necessary to make some refactoring in the code where List<T> was being used. At first, replacing at least the return of a method from IList<T> to IEnumerable<T>. With this change, some compilation errors appeared, the method Add(T) was missing. But with ICollection<T> the code worked normally. In some other cases the IEnumerable<T> met the need because it only had to scroll through the list of items returned.

Later, we found a situation that was necessary to access a specific item of the structure, which was solved using the IList<T> interface in the return. Then a AddRange(IEnumerable<T>) method of List<T> was being used, which could easily be replaced with an extension method for ICollection<T>.

But after all these the question number two came up: Were all operations being conducted in the correct place? Since the return of each method was more conscious, it was easier to notice that certain classes were doing more than they should.

At the end, the refactoring was successful, returns of all methods that were using List<T> have been replaced by an appropriate interface. With a little more research it was possible to notice that not only developers accustomed with the List interface in Java were referring to List<T> in C#, but many people use the reference to List<T> due to resources provided by the implementation. A method as AddRange(IEnumerable<T>) could be called anywhere. A tempting proposal. However, relying on abstractions makes the code to become more flexible. And relying on interfaces that only contains the necessary functionality, limited to not try to do in a class which should not be her responsibility.