An experienced Java developer colleague of mine has recently transferred into a .NET based team. He asked me, aside from the obvious things like reading up on the differences between C# and Java and getting a reference book or two on parts of .NET, what are the common practices or attitudes of .NET developers? How do they differ from your typical Java developer?
I think it’s a great question, and it got me wondering – what are the typical behaviours of a .NET developer? What qualities (or lack of!) characterise the average .NET developer? So having worked with quite a few .NET developers in the last decade, I thought I’d share my thoughts on how I see as what the average .NET developer is like, in terms of skills and attitudes.
The attributes of a .NET Developer
Before I jump in, I should point out that firstly, my experiences might not reflect what you have seen; and secondly, that this is what I have seen of a “typical” .NET developer that has some experience – but there are definitely those that I have worked with that did not fit the profile below.
The average .NET developer – let’s call him Bob – generally does not have a great grasp of the GoF design patterns. He may actually use some of them day-to-day, but without realising the application to a proper design pattern. He knows the names of two or three popular patterns such as Factory and Singleton, but often struggles to actually identify opportunities to apply them in a real-world scenario.
Bob sees himself as a client of the services offered by Visual Studio and the .NET framework, and sees little reason to understand why things work the way that they do. This includes the C# compiler, code generation features of Visual Studio, and the classes in the framework itself. This is by no means a bad thing – after all, these things are there to provide services to the developer – but there is often a real lack of understanding with what’s going on under the hood. Situations such as these might be applicable to Bob: –
Bob compiles lots of code every day, but might not know the process of what happens in order to make an executable program.
Bob uses foreach loops all the time, but does not know how they relate to IEnumerable.
Bob loves LINQ, but does not know what deferred execution is, or how query operators relate to extension methods.
Bob loves Entity Framework 4, but does not know what IQueryable is.
He uses List<T> all the time – but has no idea how to write his own generic classes.
Now, the sort of thing above that I’m talking about is not referring to being able to describe the lines of C# and IL that are generated when you use the “yield” keyword – but to at least have an understanding of how state machines fit in with it.
Test Driven Development
Bob has heard of TDD, and thinks it sounds like a great idea, but for the time it would take to apply it. He might even write unit tests from time to time. However, he is not experienced in the art of writing AAA unit tests, or in understanding the difference between testing a single class rather than writing an integration test which cuts across multiple tiers. He might use unit tests, but does not have enough confidence in them to rely on them – so he still wants to manually test the same bit of code out in the debugger as well from time to time.
Bob is happy to use code generation tools that he is aware of in order to rapidly fulfil business requirements, such as the Windows Forms designer, or the RIA Services domain service generator – IMHO a good thing. But he sees these things as tools without wanting to know what it does behind the scenes. What code does it generate? At the same time, he will often be content to write reams of boilerplate code manually rather than create a code generation tool himself, or to ask whether there is another tool out there that will do the job for him.
The Commercial Reality
Bob will sometimes see the importance of writing high quality, maintainable code as an optional nice-to-have in the quest to meet tight deadlines and timescales. He will often prefer the short-term goal of achieving the business requirement of today than building one that can more quickly deliver the dozen business requirements that must be delivered by the end of next week.
Why is this?
The above may sound unfair to many developers. After all, if you’re able to write software today in such a manner, what’s the problem? Well, for one, you could be doing the same thing in much less time, and therefore delivering far better value to your client / company.
Years ago the average C++ developer could not get by without a knowledge of what a pointer is, or what malloc() does, or how to write an efficient sort algorithm. Nowadays the barriers to entry in the world of .NET are much lower. In itself this is a good thing – anything that makes it easier to code by getting rid of having to write boilerplate code gets a thumbs up from me. But it’s also important that we as developers understand the “how things happen” as well as the “what they do”.
Professional development is still, to my mind, a highly skilled trade that we are constantly learning about, and we need to remember that just because we can easily write an application that can communicate over a network, save to a database, give error handling etc. with relative ease, it doesn’t mean that we can or should forget what’s going on behind the scenes.