views:

650

answers:

8

I have been looking at the source code for Microsoft .NET Libraries such as System.Web...... Whenever I look inside the code, I see flags, events, a whole ecosystem of rather complicated code which seems like overkill to do a pretty simple thing. It's filled with absolutely everything. I'm not sure I saw a simple piece of code inside there without it being linked to dozens of flags and stuff.

A lot of the code seems redundant but I have a feeling there must be a reason why it's there - I mean, it's Microsoft with their army of genius programmers who are programming this stuff.

It's making me wonder, should I be coding stuff to that complexity? It feels like I'm missing some knowledge and there must be a good reason why they write stuff to that complexity. Is there something someone isn't telling me? Why is the code so complex when it seems like it could be simpler?

+1  A: 

How are you looking at this source code? Is it through a decompiler? If so, that's not how they wrote it; it's just how the decompiler has interpreted.

Anyway, when programming, your goal is to make your application simple, not complex.

Noon Silk
He probably looked at it via .NET source server.
Pavel Minaev
My bet is that it was just through Reflector as suggested by silky but I could be wrong.
Dinah
A: 

I'd imagine Microsoft feels an enterprise product needs to be extremely robust and cover more edge cases then the competition.

Then again....

Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.

Antoine de Saint-Exupery

ChaosPandion
+13  A: 

The "complexity" of the source code of the .NET Framework libraries is a necessary evil. Also, the developers at Microsoft seem to have the resources (other .NET Framework developers) to be able to utilize many more features of .NET and the Framework that you (the average developer) and I may not be aware of. Plus there's plenty of compatibility things in there so use cases and features for many, many scenarios are includes; not just the most commonly used ones.

Also, it may be "complex" to you, but "simple" to the person that wrote it. All you can do is what the rest of us do... Learn how to do stuff by looking at the code.

Additionally, the source code viewed through .NET Reflector isn't as they wrote it, its a decompilation of the compiled code. And, the compiler will perform it's own "optimizations" at times. If you are viewing the source code that Microsoft distributes themselves, then you're looking at the real thing.

Chris Pietschmann
+1, it is a truism in software development that it is easy to make things hard and hard to make things easy.
Ozan
Maybe highlite the last item a bit, and suggest to have him take a look at Mono's source.
Dykam
A: 

A lot of enterprise applications depend on .NET libraries. They're just obligated to cover every single corner of their libraries if they want to keep developers interested.

Sergey
+30  A: 

Keep in mind that .NET Framework is in unique position - it is a set of core, foundational classes used by millions of developers around the world. As such, it has some very tight constraints in terms of performance, error handling, etc. For example, the traditional way to do argument validation is to validate arguments on entry to every method. However, sometimes you have a bunch of methods that end up calling each other, so arguments get re-validated all the time. Most often this isn't a problem, but when your method is e.g. on System.String (just an example), so it's called often from everywhere, those extra checks do add up very quick. So you have to refactor the code into a separate private method, or a bunch of methods, and have your public API perform validation only once on the API boundary, and delegate to those non-validating private methods. This complicates the code, but it gives the clients better experience.

The above was just an example, and there may be many other instances where micro-optimizations such as using ref/out, or avoiding lambdas (and using flags and other means of communicating state), is needed because the framework class/method is found from experience to be on a "hot path" often. This leads to "overcomplicated" code that you observe.

Another issue is with rare corner cases. Again, when you have those millions of developers throwing all kinds of input at your APIs and expecting them to handle all that, you start running into some very non-obvious corner cases for that input that often have to be handled in a very special way. To see what I mean, have a look at the source code for System.Uri - preferably not in Reflector, but the version that comes from .NET Framework Source Server, which comes with comments documenting why it does some very non-obvious things that it does.

In general, when writing libraries, it is almost always some trade-off between convenience (and development time) for the library authors, and convenience (and performance) for library clients. The wider your audience, the more pressed you are to shift the balance in favor of the clients.

Pavel Minaev
Well said! The ultimate goal of any library is to make things easier for the consumers which usually means more difficult/challenging for the developers writing the library itself.
Scott Dorman
Actually, if you look at system.uri in reflector, some of it looks quite poorly written (in the sense that equivalent shorter and/or more efficient code isn't hard to write), and it's unclear *and* buggy to boot. (yes, it's bitten me before, which is why it's annoys me: http://social.msdn.microsoft.com/Forums/en/ncl/thread/5ce22ebc-55ed-4de7-afa8-862620e45656). It's possible some obfuscation is due to reflector, of course; but the bugginess remains.
Eamon Nerbonne
Maybe I've just had bad luck; but System.Uri isn't the only .NET code with outright bugs or crippling design flaws I've run into. I can well imagine that many of these were caused by the high complexity of the code the OP mentions.
Eamon Nerbonne
+3  A: 

Well, thats what a frameworks is for: Hide complexity. Its complex and manage thousands of of interconnections to make you never have to worry about them.

Havenard
+1  A: 

Have you explored the mono equivalents to see if Novell's implementation of the .NET spec has proved to be cleaner and more elegant? Also have you looked at the public specs that are avaialable for much of the CLI and BCL?

Worst case you can write your own, open-source it, and be famous--provided it works.

STW
+10  A: 

As Pavel stated, the .NET Framework itself isn't an application, it's a core runtime that other developers are able to build upon to create their own applications. As a result, what may seem complex or complicated to the casual observer is there for a variety of reasons, the least of which are performance, reliability, and stability.

You are correct in that there is an entire ecosystem behind the code built largely from real-world experience over the last 10 years (from the .NET Framework side) and beyond (from the Win32 API side) that flavor some of the decisions made about how the code should be written. Combine that with a vastly deeper knowledge of not just the .NET Framework itself but also how other pieces of the .NET Framework are architected allow code to take advantage of highly optimized paths that most developers wouldn't think of or even be aware of.

The other thing to keep in mind is that different sections of the .NET Framework are written by different teams. It is absolutely a collaborative effort, but there are a lot of internal rules that must be followed for how code is written - going beyond just the syntax issues and focusing on performance, etc. This is mainly due to the level of impact code within the Framework has since what might appear overkill to you or I is actually a huge performance concern for the Framework or is in place to work around a little-known bug in a specific Win32 API or handles some obscure edge-case that 99% of developers will never encounter.

Think of it this way...the .NET Framework was written with the goal of making the simple things trivial and the difficult things possible. What seems simple to us on the outside is a direct result of that effort and the simpler it seems the harder it was to develop.

Unless you are writing your own library/framework that will be used in the same (or similar) ways to the .NET Framework you probably don't need to write your code to the same level as what you see in the Framework. There are certainly valuable lessons that can be learned from close examination of the code (as long as it really is through something like the .NET Source Server or the SSCLI and not reflector).

Scott Dorman