Tuesday, October 26, 2004
« Apple of my I, Mac | Main | PostXING »

[Updated 10/29/2004 with item #6]

I figured that for my 100th post I'd put something out there that I hope to get lots of feedback on.

Each day as I'm coding I invariably stumble across a language feature that just doesn't sit right with me.  That, or I get to thinking, I wish the BCL's supported X function or Y capability.  While I'm not coding, however, I tend to forget these items until I once again go crashing headfirst up against it.

I've given this some thought, but will probably be amending it a bit here in the next few days as I expect I'll encounter a few more.  So, without further ado, here's my .NET wish list (NOTE: I'm not addressing several issues that I know will be fixed within Whidbey such as scoped accessors on properties, etc):

1. CONSTANTS

I really wish I could declare globals (public constants) at the namespace level without having to resort to an enumeration or a class when the values aren't conceptually enumerated or non-integers.  I'd love the ability to create public and/or internal constants like this:

namespace SomeNamespace {
   internal const int MaxIdLength = 15;
  
   public class Employee {
      public const int MaxNameLength = MaxIdLength;
      // ... class code here ...
   }
}


1a. DEFINES

Along the same lines as constants, having the ability to perform a #define would be very powerful.  Where a constant can potentially be exposed outside the library as a value, a #define only has applicability to the compiler preprocessor.

#define S_RES_APPLICATION_TITLE 10001

namespace SomeNamespace {

   internal sealed class Res {
      internal static string GetString(int id) {
         // return the designated resource value
      }
   }
 
   internal sealed class EntryPoint {
      public static void Main() {
         System.Windows.Forms.MessageBox.Show(Res.GetString(S_RES_APPLICATION_TITLE));
      }
   }
  
}


Now there might be some issues of type safety here that would need to be addressed, but this capability would be extremely enabling and powerful...hearkening to what C++ developers can already do.

2. TRY..CATCH..FINALLY VARIABLES

I am of the firm belief that if a variable is declared within the try block its scope should extend to both the catch and the finally blocks.  As it stands, in order to use a variable in the various blocks you must declare it outside the try..catch..finally.  In other words, if I declare a SqlConnection within a try I can't Dispose() of it in the finally...I must declare it before the try.  This can lead to poor code.  First of all, the object's scope now extends beyond its intended usage, a bad practice as far as I'm concerned.  This would be ideal:

public string GetName(int id) {
   try {
      SqlConnection cn = new SqlConnection("...");
      // get the name and return it
   }
   finally {
      if ( null != cn ) cn.Dispose();
   }
}


There might very well be some technical reasons behind why this is so danged difficult, but I believe it would lead to much clearer code and the developer's intentions would be more easily maintained.

3.  SCOPED INHERITANCE

I get fed up with having to scope my base classes the same as the deriving classes (or vice versa).  Oftentimes, I am wanting to declare a base class to be internal to my assembly, but have a public class that derives from it.  I am using the base class internally for private functionality and object organization, but I don't need it exposed.  Yes, I know I can probably use an internal interface and a private class to accomplish something similar, but that's not what I want to do.

If in fact I do have to expose the base class (which I might be amenable to), I'd at least like to have it internally abstract and publically sealed.

Ideally:

internal abstract Base {
   // ... some methods here ...
}

// here sealed would be implied by virtue of the fact that the
// abstract base class is not publically exposed

public class Derived : Base {
   // ... implementation ...
}


Willing to Accept:

public sealed internal abstract Base {   // or something like that
   // ... some methods here ...
}


Or even:

internal abstract Base {
   // ... some methods here ...
}

public sealed class Derived : internal Base {
   // ... implementation ...
}


4.  STRING.ZERO()

In an effort to provide more out of the box security, I believe the String class should provide a .Zero() method.  This method would be a void method, but when called would zero out/blank out the contents within the string.  I'd imagine that internally it would call SecureZeroMemory().

Yes, we could probably accomplish this using unsafe methods, but that's not a recommended/supported route.  Instead support for this should be built into the framework.

string pwd = txtPassword.Text;
// of course this would have been acquired encrypted and/or securely
// ... use the password variable to login, access a resource, etc
// now that we're done with it, clear it out
pwd.Zero();

This could potentially have further reaching impacts; it could adversely affect parameters, etc, but would provide a nice mechanism to blank out information that you don't want dangling in memory when you're done with it.

5. INDEXERS

It's pretty darned convenient to be able to add an indexer to your class.  It would be very powerful to have this functionality extended to support indexers on properties rather than just on this.  This capability would enable a more flexible and powerful mechanism for indexing into collections internal to your classes without having to write accessors that don't exhibit an indexing mechanism via [].

public sealed class Quote {

   private QuoteLineItem[] _lineItems;
  
   public QuoteLineItem LineItem[int i] {
      get { return _lineItems[i]; }
   }
}


6. NOITEMSTEMPLATE

This is pretty esoteric, but since day 1 that I got into .NET development this one has bugged me and I just remembered it today.  The ASP.NET Data(Grid|List) and Repeater controls have some niceties and are pretty powerful controls.  Each of these controls allows you to define templates for how records are rendered in the browser via the <itemTemplate>.  But what if your controls is being bound to a data source that doesn't have any records?

In this case you have to perform custom server logic and then determine the proper course of action or your content is going to look horrible in the browser.  I think there should be a <noItemsTemplate> that allows you to specify what should render on the browser in the even no items were bound.  This would return control back to the UI designers to lay out the page as they see fit.

<asp:Repeater id=rpt runat=server>
   <noItemsTemplate>
      We're sorry, there are no employees that match your query.
   </noItemsTemplate>
   ...
</asp:Repeater>

Tuesday, October 26, 2004 5:34:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback