Annoyances in the .Net Framework

This post is 100% whine.  It’s where I get to complain about how parts of the .Net Framework are put together.  I don’t intend to be constructive.


Why are System.IO.File & System.IO.Directory static classes?  They should be instance classes that do what FileInfo and DirectoryInfo do today.  I write static classes in my code to make up for holes someone else’s library.  NDP is the end of that chain.

The Path class is nasty, too.  There’s no PathInfo or some such.  There’s no FileInfo.GetExtension(), so I get to write junk like “Path.GetExtensions (fileInfo.FullName)“;

Weak types

Why does is System.Environment.CurrentDirectory a string, instead of a DirectoryInfo?

Why does RegistryKey.SetValue take ‘object value’?  What happens when you pass in, say, a System.Console?  One improvement would be to make overloads for each supported type (there are only 6).  SetDWordValue (int) seems much more sane.  Let’s keep going: create a RegistryKeyValue type, and let it expose value-specific operations.  If you derive it to each of the support types, you can use nice OO constructs like:
     if (myRegistryValue is RegistryKeyValue.DWord)

Namespace arrangements

Why is Process in System.Diagnostics?  Does this make sense to anyone?

Lack of class nesting

Look in System.Windows.Forms.  See MessageBox, MessageBoxButtons, MessageBoxDefaultButton, MessageBoxIcon, MessageBoxOptions.  Can we please use nested classes, instead?  Then you would write MessageBox.Buttons, etc.  It makes your intellisense list shorter & quicker to navigate.

ConsoleColor should be Console.Color, too.  (new in Whidbey)

Same with Registry / RegistryHive / RegistryKey

Edit: moan about Sytem.IO.Path

Comments (10)

  1. Hans Jergen Ohff says:

    These are raided, right?

  2. J. Daniel Smith says:

    While you said this was a "whine", there is *A LOT* of value in Microsoft getting such things "right".

    The reason is that people will use the BCL as a model for their classes. If System.Environment.CurrentDirectory as a string is good enough for Microsoft, then MyApp.Foo.Pathname can be a string too. And why are you writing nested classes (which results in such a large file) – Microsoft didn’t do it that way.

  3. Scott says:

    Amen, brother! Many of the things you mention have made me unspeakably frustrated. I thought the .NET framework was the opportunity to start over.

    It’s unfortunate how the past haunts us. A lot of the weirdnesses you see in today’s .NET framework seem to derive from MFC patterns, which in turn is a thin layer on top of the Win32 APIs.

  4. MartinJ says:

    With the RegistryKey.SetValue method, it would make sense to just expose overloads for each supported type instead of a different method for each one.

    So, you’d have SetValue(int32), SetValue(string), … very similar to what the StringBuilder does in its Append method.

  5. MrtinJ: I definitely see why you might choose to design it that way. There’s certainly plenty of precedent.

    However, one thing I’m trying to call out is that the "types" available in registry keys are not the same thing as types in the CLR. They are quite different entities. There are some convenient mappings (REG_DWORD = System.UInt32) to be sure, but what do you do with REG_EXPAND_SZ?

    A more relevant precedent is the mapping of COM types to CLR types,

    I think this is a question of style.

  6. Louis Parks says:


    I’d say the .NET Framework was a fresh start. It isn’t, however, a perfect framework. Better than the past, but not perfect.

  7. The reason ConsoleColor is the correct name is because it extends Color. If my class is "using" both System.Drawing and whatever namespace contains Console, I don’t want the .Color to be ambiguous.

  8. Michael: good point, but nested classes don’t have that problem. As long as you’re coding outside of ‘Console’, the shortest possible class name is ‘Console.Color’.

    Thanks for your thoughts.