Tag Archives: Code

Nullable Types in C# 2.0

I was reading about Nullable Types in the C# 2.0 specification for the
.NET Framework 2.0 today. I am surprised I didn’t find out about this
feature long ago, goes to show that you learn something new every day.

So what are Nullable Types?

Simply put, Nullable Types are value types that a can be assigned null. The following line of C# will give you a compiler error:

int y = null;

A System.Int32 is not a reference type (it is a value type), and can
therefore not be assigned a null value, however, the next line of code
will compile under the 2.0 framework:

int? y = null;

Adding a question mark after the type turns the System.Int32 value type
into a Nullable Type. The line above, is in fact, shorthand for the line
below:

System.Nullable<int> y = null;

The System.Nullable<T> generic class is used to create value type variables that contain an undefined state. The HasValue property of this class will return true if the contained variable has an assigned value, or false if it null.  The Value property will return the value of the property, or throw a System.InvalidOperationException if the contained variable is unassigned.

Why use Nullable Types?

How many times have you defined an integer in your code, and assigned it to -1 in the constructor (or definition) as meaning undefined
What happens of your code needs to change to allow negative numbers,
but you still need to determine if a value has been assigned to your
variable?  With Nullable Types, you can assign null to your
variable and test to see if the variable has been assigned at runtime.

I am presently writing a piece of code that uses reflection to get a
list of properties in a class, and then output an XML tag for each
property if the property value is not null.  Using Nullable
Types, I do not have to worry about value types outputting if their
value has not been assigned.

Casting from Nullable Type to value type.  The following lines of code will fail compilation

int? y = null;
int x = y;

The following will compile, but throw an exception if y is null:

int? y = null;
int x = (int)y;

The following will also compile, but throw an exception if y is null:

int? y = null;
int x = y.Value;

What is needed in the above examples, is an operator that will assign a
default value if the nullable variable type is unassigned.  It
just so happens that one exists. The following line will assign -1 to x
if y is null:

int? y = null;
int x = y ?? -1;

Nullable types work fine with most of the basic operators, bool& is an interesting one.  The table below defines how logical and and logical or work with two boolean nullable types:

bool? x, y;

x

y

x&y

x|y

true

true

true

true

true

false

false

true

true

null

null

true

false

true

false

true

false

false

false

false

false

null

false

null

null

true

null

true

null

false

false

null

null

null

null

null

So what are you waiting for? It’s time to start using the .NET
Framework 2.0, with it’s array of nice new features, including Nullable
Types.

Event catch-up in ASP.NET 2.0 Controls

Pop quiz, what is wrong with the following class?

public class MyPlaceHolder : PlaceHolder
{
protected override void OnInit(EventArgs e)
{
Page.Trace.Write(this.ID, “In OnInit”);
base.OnInit(e);
}

protected override void OnLoad(EventArgs e)
{
Page.Trace.Write(this.ID, “In OnLoad”);
base.OnLoad(e);
}

protected override void OnUnload(EventArgs e)
{
Page.Trace.Write(this.ID, “In OnUnload”);
base.OnUnload(e);
}

protected override void OnPreRender(EventArgs e)
{
DropDownList myDropDownList1 = new DropDownList();
myDropDownList1.ID = “_myDropDownListDynamic1”;
myDropDownList1.Items.Add(new ListItem(“One”, “one”));
myDropDownList1.Items.Add(new ListItem(“Two”, “two”));
this.Controls.Add(myDropDownList1);
base.OnPreRender(e);
}
}

The class above is a custom server control that derives from an ASP.NET
PlaceHolder control.  This example is a stripped down version of a
class I am currently working on this week (which loads controls
dynamically from custom XML).  I chose the PlaceHolder control to
derive from because I needed a container control, in which to hold my
dynamically instantiated controls – the PlaceHolder control is designed for,
and ideal for this purpose.

I ran into a problem with persistence of property values belonging to
dynamic controls when contained in my custom MyPlaceHolder
control.  In the above example I have created a DropDownList
control dynamically in the OnPreRender method, and added it to the
controls collection of MyPlaceHolder, which, as it turns out is a problem…..

Those of you who know enough about how ASP.NET works (1.1 and 2.0), will know about “catch-up”:

When controls are declared statically in an ASPX page, ASP.NET
instantiates these controls, adds them to an in-memory control tree,
and then calls various event methods on each control, and child
controls recursively, before the page is rendered.  (I have
included the order of events of all controls in ASP.NET later in this
post).

When a control is created dynamically, the time in which the control is
instantiated is at the mercy of the developer. For this reason, ASP.NET
plays “catch-up” and arranges to call all missed event methods so that
the control is in sync with it’s container. Using the above code as an
example – after instantiating the drop down list control and adding this
control to the controls collection of the placeholder, ASP.NET will
call the OnInit, LoadViewState, and OnLoad event methods of the drop down list control,
after which the drop down list control will have caught up to the pre-render event of the
placeholder container.

So, why do I loose persistence of property values in my drop down list control, specifically the selected index property? 

When ASP.NET plays “catch up”, the framework will call some, or all of
the OnInit, LoadViewState, OnLoad, and OnPreRender methods, depending
on the current state of the containing control.  The methods to process post back data are not called during catch-up.

The following AddedControl method exists as part of the Control class
in the ASP.NET 2.0 framework (version 1.1 will have similar code), and
demonstrates “catch-up”, using the current state of the control. Notice
that no call exists to load post data.

protected internal virtual void AddedControl(Control control, int index)
{
if (control.OwnerControl != null)
{
throw new InvalidOperationException(SR.GetString(“Substitution_NotAllowed”));
}
if (control._parent != null)
{
control._parent.Controls.Remove(control);
}
control._parent = this;
control._page = this.Page;
control.flags.Clear(0x20000);
Control control1 = this.flags[0x80] ? this : this._namingContainer;
if (control1 != null)
{
control._namingContainer = control1;
if ((control._id == null) && !control.flags[0x40])
{
control.GenerateAutomaticID();
}
else if ((control._id != null) || ((control._occasionalFields != null) && (control._occasionalFields.Controls != null)))
{
control1.DirtyNameTable();
}
}
if (this._controlState >= ControlState.ChildrenInitialized)
{
control.InitRecursive(control1);
if (((control._controlState == ControlState.Initialized) && (control.RareFields != null)) && control.RareFields.RequiredControlState)
{
this.Page.RegisterRequiresControlState(control);
}
if (this._controlState >= ControlState.ViewStateLoaded)
{
object obj1 = null;
if ((this._occasionalFields != null) && (this._occasionalFields.ControlsViewState != null))
{
obj1 = this._occasionalFields.ControlsViewState[index];
if (this.LoadViewStateByID)
{
control.EnsureID();
obj1 = this._occasionalFields.ControlsViewState[control.ID];
this._occasionalFields.ControlsViewState.Remove(control.ID);
}
else
{
obj1 = this._occasionalFields.ControlsViewState[index];
this._occasionalFields.ControlsViewState.Remove(index);
}
}
control.LoadViewStateRecursive(obj1);
if (this._controlState >= ControlState.Loaded)
{
control.LoadRecursive();
if (this._controlState >= ControlState.PreRendered)
{
control.PreRenderRecursiveInternal();
}
}
}
}
}

My drop down list box  looses persistence because, by the time the
control is instantiated at the pre-render stage, the time for loading
post back data has passed. 

Loading of post back data is in fact performed by the Page class in the
ProcessPostData method, which is called twice by the ProcessRequestMain
method – once before the OnLoad method (before OnPreLoad in ASP.NET
2.0), and again (if not called prior) just after the OnLoad method
completes. This loading of post data before and after OnLoad allows the
developer to add dynamic control instantiation code in the most derived
version of OnLoad method without having to worry about when the base
version is called.

More details about event “catch-up” can be on this excellent post. Also,
check out the Page.ProcessRequestMain, Page.ProcessPostData and
Control.AddedControl methods in the framework using Lutz Roeder’s
Reflector
.

As promised earlier, here is a list of the event methods called by ASP.NET 2.0 in a page render life cycle:

Page Life cycle methods in ASP.NET 2.0

Method Active
Constructor Always
Construct Always
TestDeviceFilter Always
AddParsedSubObject Always
DeterminePostBackMode Always
OnPreInit Always
LoadPersonalizationData Always
InitializeThemes Always
OnInit Always
ApplyControlSkin Always
ApplyPersonalization Always
OnInitComplete Always
LoadPageStateFromPersistenceMedium PostBack
LoadControlState PostBack
LoadViewState PostBack
ProcessPostData1 PostBack
OnPreLoad Always
OnLoad Always
ProcessPostData2 PostBack
RaiseChangedEvents PostBack
RaisePostBackEvent PostBack
OnLoadComplete Always
OnPreRender Always
OnPreRenderComplete Always
SavePersonalizationData Always
SaveControlState Always
SaveViewState Always
SavePageStateToPersistenceMedium Always
Render Always
OnUnload Always

Firing multicast delegate events

I am currently writing an ASP.NET server control, which exposes a
number of custom events.  I was looking through my code archives
for a helper class, which will safely call handler methods of a
multicast delegate, when an event is triggered.  I found the class
I was looking for, and decided to publish it here on my blog for future
reference.

A quick note on multicast delegates – Multicast delegates are delegate
instances that are derived from System.MulticastDelegate
and can have
more than one instance in their invocation list – essentially they are
delegates
that allow assignment of multiple handler methods. When dealing with
multicast delegates, a question arises about how to deal with
exceptions thrown in handler methods. When the framework executes a
multicast delegate, all handler methods in the invocation list are
executed sequentially.  If one of the invoked handler methods
should throw an exception, the remaining handlers in the
list, yet to be executed, are not invoked.

So, let’s say that we have a custom event on a control (events are
multicast delegates). The containing code of the control subscribes to
the control’s event with two different event handlers.  The event
fires, causing the first handler to be invoked, which then happens to
throw an exception.  The second event handler will never get
called, which could cause serious malfunction or resource leakage in
the application if the handler had an important part to play. The
helper class, posted below, alleviates this problem by invoking the
handler methods in a delegate invocation list dynamically, whilst
trapping exceptions.

The helper class exposes methods to execute a multicast delegate, both
synchronously and asynchronously.  The synchronous method returns
the list of thrown exceptions, whilst calling all handlers in the
invocation list.  The asynchronous method ignores any exceptions
and calls each handler in the invocation list on a separate thread.

public class EventHelper
{
///
/// Asynchronous delegate.
///
private delegate void AsyncFire(Delegate del, object[] args);

///
/// Static instance of asynchronous delegate.
///
private static AsyncFire _asyncFire = new AsyncFire(InvokeDelegate);

///
/// Call back for asynchronous delegate call.
///
private static AsyncCallback _asyncCallback = new AsyncCallback(InvokeDone);

///
/// Fire synchronously.
///
/// If an event handler throws an exception ignore it and move onto the next handler.
/// Multicast delegate.
/// Args.
public static Exception[] Fire(Delegate del, params object[] args)
{
List exceptions = new List();
// If delegate has no handlers then do nothing.
if (null != del)
{
// Iterate the handlers.
Delegate[] delegates = del.GetInvocationList();
foreach (Delegate sink in delegates)
{
try
{
// Invoke.
sink.DynamicInvoke(args);
}
catch (Exception ex)
{
exceptions.Add(ex);
}
}
}
return exceptions.ToArray();
}

///
/// Fire asynchronously.
///
/// Each handler is fired in an thread from the thread pool.
/// Multicast delegate.
/// Args.
public static void FireAsync(Delegate del, params object[] args)
{
// If delegate has no handlers then do nothing.
if (null != del)
{
// Iterate the handlers.
// Cannot call multicast delegate asyncronously, must process
// each handler separate.
Delegate[] delegates = del.GetInvocationList();
foreach (Delegate sink in delegates)
{
// Invoke using a thread from the pool.
_asyncFire.BeginInvoke(sink, args, _asyncCallback, null);
}
}
}

///
/// Invoke container delegate.
///
/// Delegate.
/// Args.
static void InvokeDelegate(Delegate del, object[] args)
{
del.DynamicInvoke(args);
}

///
/// Called when asynchronous delegate call complete.
///
/// Asynchronous result.
private static void InvokeDone(IAsyncResult ar)
{
// Clean up.
_asyncFire.EndInvoke(ar);
}
}

HTML to XHTML using SGMLReader

Chris Lovett wrote a wonderful .NET library called SGMLReader, which,
when passed a regular HTML file will spit out XHTML.  The library
relies on SGML parsing and uses a DTD (Document Type Definition) file to parse
unformatted HTML. 

I’ve been playing with Chris’s library this
week and trying to convert HTML to XHTML on the fly using an ASP.NET
Http Filter. The code below consists of the following:

  • An HttpModule, which sets the filter property of the response object for all ASPX page requests.
  • An Http filter, which is a custom stream, to manipulate the HTML content for the requested page.
  • The entry in the web.config file, required for the module to operate.

So, how does the code work?

To understand my code, you should know a little about how Http modules
work in ASP.NET. I am not going to breach this subject in this post,
but you can out all you need to know about Http modules on MSDN
My module code interjects with each incoming web request sent through
IIS, checks to see if an ASPX page has been requested, and if so, sets
the filter property of the response object to a new instance of XhtmlFilter.

When ASP.NET is ready to push processed HTML content back to the client
browser, via IIS, it uses the filter property in the response
object.  The default filter used by ASP.NET is -:
System.Web.HttpResponseStreamFilterSink.  However, it is possible
to reassign the filter property a custom filer, which will perform so
additional processing before forwarding the content to the default
filter.  This exactly what my filtering code does.  My XhtmlFilter
class is a stream derived class, which captures incoming HTML data from
ASP.NET, converts it to XHTML using SGMLReader, and then forwards the
changed content to the default filter.

The XhtmlFilter class inherits from a base class – HttpFilterBase, which abstracts away the stream functions not supported by Http
filters.  Inside my filter class I make use of a MemoryStream
object to capture all the HTML content pushed by the framework before
processing content with SGMLReader. As the SGMLReader parses the HTML
data the converted XHTML is streamed out to the default filter, and out
to the client browser.

The code follows….

XhtmlFilterModule.cs

using System;
using System.Web;

namespace HTML2XHTML.HttpFilters
{
public class XhtmlFilterModule : IHttpModule
{
public void Dispose() {}

public void Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(ModuleBeginRequest);
}

private void ModuleBeginRequest(object sender, EventArgs e)
{
// See if request is for a ASPX page.
HttpRequest request = HttpContext.Current.Request;
if (request.Url.AbsolutePath.EndsWith(“.aspx”))
{
// Install the filter.
HttpResponse response = HttpContext.Current.Response;
response.Filter = new XhtmlFilter(response.Filter);
}
}
}
}

XhtmlFilter.cs

using System;
using System.IO;
using System.Text;
using System.Xml;
using Sgml;

namespace HTML2XHTML.HttpFilters
{
public class XhtmlFilter : HttpFilterBase
{
private MemoryStream _memStream = null;
private BinaryWriter _writer = null;

public XhtmlFilter(Stream baseStream) : base(baseStream)
{
_memStream = new MemoryStream();
_writer = new BinaryWriter(_memStream);
}

public override void Write(byte[] buffer, int offset, int count)
{
// Check if stream is open.
if (Closed)
throw new ObjectDisposedException(“XhtmlFilter”);
// Write to the memory stream.
_writer.Write(buffer, offset, count);

}

public override void Flush()
{
_writer.Flush();
}

public override void Close()
{
// Seek to the beginning of the memory stream.
_memStream.Seek(0, SeekOrigin.Begin);
// All output has been written to the stream – process the HTML.
SgmlReader sgmlReader = new SgmlReader();
StreamReader streamReader = new StreamReader(_memStream);
XmlTextWriter xmlWriter = new XmlTextWriter(BaseStream, Encoding.UTF8);
sgmlReader.CaseFolding = CaseFolding.None;
sgmlReader.DocType = “HTML”;
sgmlReader.InputStream = streamReader;
sgmlReader.Read();
while (!sgmlReader.EOF)
xmlWriter.WriteNode(sgmlReader, true);
// Close the writer.
xmlWriter.Flush();
xmlWriter.Close();
// Close the reader.
streamReader.Close();
sgmlReader.Close();
// Close the base version.
base.Close();
}
}
}

HttpFilerBase.cs

using System;
using System.IO;

namespace HTML2XHTML.HttpFilters
{
public abstract class HttpFilterBase : Stream
{
private Stream _baseStream;
private bool _closed;

protected Stream BaseStream
{
get { return this._baseStream; }
}

public override bool CanRead
{
get { return false; }
}

public override bool CanWrite
{
get { return !_closed; }
}

public override bool CanSeek
{
get { return false; }
}

protected bool Closed
{
get { return _closed; }
}

public override long Length
{
get { throw new NotSupportedException(); }
}

public override long Position
{
get { throw new NotSupportedException(); }
set { throw new NotSupportedException(); }
}

protected HttpFilterBase(Stream _baseStream)
{
this._baseStream = _baseStream;
this._closed = false;
}

public override void Close()
{
if (!_closed)
{
_closed = true;
_baseStream.Close();
}
}

public override void Flush()
{
_baseStream.Flush();
}

public override int Read(byte[] buffer, int offset, int count)
{
throw new NotSupportedException();
}

public override long Seek(long offset, SeekOrigin origin)
{
throw new NotSupportedException();
}

public override void SetLength(long value)
{
throw new NotSupportedException();
}
}
}

Module entry in web.config

IPostBackDataHandler and IPostBackEventHandler

I’ve been messing around with post back handler in ASP.NET today, and I
found out a few points of interest.  Firstly, a description of the
two interfaces used with server controls to handle post backs:

IPostBackEventHandler – Implemented by server controls that wish to handle post back events. The RaisePostBackEvent
method is invoked by the framework when the control that implements
this interface method is the source of a page post back – such as a
submit button.  The RaisePostBackEvent method is expected to call an event delegate on the control, suck as Click.

IPostBackDataHandler – Implemented by server controls that wish to handle posted form data state changes. The LoadPostData
method is invoked by the framework when the control that implements the
interface method has posted some form data.  This method should
compare the posted data (contained in a NameValueCollection, keyed with
a passed unique post data key) with the data internal to the control,
to see if the user changed the data on the page.  This method is
expected to return true if the state of the data has changed.  The
framework checks to return value of LoadPostData and calls the
RaisePostDataChangedEvent method if the return value was true.  The RaisePostDataChangedEvent methods is expected to call a changed event delegate on the control.

Below is is the source code to a couple of server controls that I had implemented to test these interfaces. 

public class MyButton : Control, IPostBackEventHandler
{
public string Text
{
get { return ViewState[“myText”] as string; }
set { ViewState[“myText”] = value; }
}

public delegate void ClickHandler(object sender);

public event ClickHandler Click;

public MyButton()
{

}

#region IPostBackEventHandler Members

public void RaisePostBackEvent(string eventArgument)
{
string res = eventArgument;
if (null != Click)
Click(this);

}

#endregion

protected override void Render(HtmlTextWriter writer)
{
writer.WriteLine(“”);
}

}

public class MyTB : Control, IPostBackDataHandler
{
private string VSID
{
get { return “myText” + this.UniqueID; }
}

public string Text
{
get { return ViewState[VSID] as string; }
set { ViewState[VSID] = value; }
}

public delegate void ChangedHandler(object sender);

public event ChangedHandler Changed;

#region IPostBackDataHandler Members

public bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection values)
{
String presentValue = Text;
String postedValue = values[postDataKey];
if (!presentValue.Equals(postedValue))
{
Text = postedValue;
return true;
}
return false;
}

public void RaisePostDataChangedEvent()
{
if (null != Changed)
Changed(this);
}

#endregion

protected override void Render(HtmlTextWriter writer)
{
writer.WriteLine(“”);
}
}

Point #1:  Initially both controls were not working.  After
pulling out some hair, I figured out that each rendered control must
output a “name” attribute with a unique value. Without this attribute
the framework has no way of calling either the RaisePostBackEvent or LoadPostData
methods on the correct control instance. Adding an ID field is not
enough, for some reason ASP.NET insists on the “name” attribute.

Point #2: IPostBackDataHandler
makes no sense on controls that do not change their state between page
posts – duh.  Sounds obvious, but that still did not stop me
spending 20 minutes trying to figure out why this interface was not
working on my custom button control. 

Point #3: I wanted to know why the string argument passed to the RaisePostBackEvent
method was null when I rendered my custom button as a regular HTML form
submit button. Even though a simple submit button will cause a post
back or sort – after all a post back is essentially a form submission –
the framework will not interpret the form submit as a true post back
without the __doPostBack JavaScript call.  This JavaScript method
has the capacity to pass an argument to the framework during a form a
post.  Adding this method to my code was a simple case of
rendering the returned string from the GetPostBackEventReference method in an “onclick” attribute.

Point #4: When comparing posted data with that of the internal state of
the data in the control, using LoadPostData,
it helps if the control persists state
of its own data in the first place.  For example, when persisting
the text value in my custom text box I used the ViewState. Had I used a
private member variable to store the internal text value, the
persistence would have been lost for each post back; because a new
instance of each control on the page is loaded for each page request.

FOR XML and ADO.NET

My esteemed colleague Sahil Malik has blogged about using FOR XML in SQL server.  The following C# example demonstrates how to retrieve XML data from a SQL Server 2K5 database as XML:

using (SqlConnection conn = new SqlConnection(“…”))
{
using (SqlCommand cmd = new SqlCommand(
“select’Rob’ as [Employee/@EmployeeName],’A cool dude’ as [Employee] FOR XML PATH(‘Staff’)”, conn))
{
conn.Open();
XmlReader reader = cmd.ExecuteXmlReader();
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element:
if (reader.HasAttributes)
{
Console.Write(“”);
}
else
Console.Write(“”, reader.Name);
break;
case XmlNodeType.Text:
Console.Write(reader.Value);
break;
}
}
}
}

How many bad developers are there in the world?

As I was reading today’s “Daily WTF” I could not help but wonder about
how many really bad developers are out there in the market place. The
following snippet was submitted to D-WTF after being found in some
production code:

public boolean checkFalse(Boolean bool)
{
if (bool.booleanValue() == Boolean.FALSE.booleanValue())
{
return Boolean.FALSE.booleanValue();
}
else
{
return Boolean.TRUE.booleanValue();
}
}

Ok, the average coder knows that this entire function
can be replaced with if (bool) {}. So, who are these people that spend
their time writing functions to replace built-in language logic? Why
are they employed? Who is interviewing them and giving them work in the software arena?

Code Comments

I have lost count of the number of times that I have been asked to work
on a piece of software written by another developer, only to find out
that the code had no comments. What typically follows is hours spent
wading through lines and lines of complex instruction to determine how
the software was intended to work before I could make any
modifications.  I can hear the groans, yes it’s the old “code
comments” debate that has been going on between software developers
since the first lines of code was punched into a machine capable of
storing and editing of instructions.

In my honest opinion I see no real good reason for the absence of code
comments.  The days of programming in a vacuum are long gone,
also are the days of programming software, which is never to be
maintained once it reaches production.  There is a strong
probability that any code that you develop today will be reviewed
and/or maintained by someone else tomorrow. Yet, there are still plenty
of developers who believe that this simplistic approach to software
documentation is a hindrance to their productivity and refuse to
comment.

Below are the excuses that I have heard from other software developers when asked why their code has no comments:

1. “I had a deadline to meet and did not have time to add comments.”
Adding code comments at the time of writing adds very little to the
overall development time of a project.  I would argue that it
actually saves time because it saves the developer having to remember
what they wrote a few days ago when coming back to a previously written
module. Comments will also save hours of work down the line when the
same piece of software is maintained or enhanced. The time required to
add comments should be considering in the original implementation
estimate.

2. “I’ll add the comments later after our software is released to production.”
Comments are an inherent part of the software implementation process,
and should not be considered as an after thought.  Adding code
comments as you develop software is easier than having to go back and
add them later. Greater accuracy of comments is guaranteed if comments
are added while the intended operation of code is fresh in the mind of
the developer.  Often is the case that developers rarely go back
and add comments to production code.

3. “Comments slow down my compilation.”
Nope! most preprocessors and compilers are optimized to skip comments
when translating code into machine instructions or intermediate
language code.  Code comments no more slow down compilation than
adding white space characters between lines of code.

4. “If no-one knows how my software works I’ll have job security.”
False! If your employer has a need to terminate your agreement, writing
uncommented code will not save your butt. Sure, it’ll cost more time
and money having someone else follow your work, but in the long run
your code will get replaced with code that is easier to maintain,
saving time and money overall.

5. “I am just too damn lazy to add comments to my code.”
If you cannot take enough pride in your work to write a good piece of
software with comments, which others can continue developing against
after your done, then you should consider another profession and stop
making life difficult for other developers who need to follow you.

6. “I plan on stiffing my employer by creating unmaintainable code and then leaving.”
You’re not going to hurt your employer, just the poor developer who follows you, which might be me.

The following are all good reasons why code comments are a good thing:

1. Your code can be maintained by someone else after you’ve moved on.
2. You’ll be harassed less by your employer if someone else can work on your code in your absence.
3. Forget what you wrote yesterday? Read your own comments, you should be able to understand them.
4. Comments above classes and methods help break up code and distinguish one method or class from another.
5. Any special circumstances or quirks in the code will be obvious to someone editing your code.
6.  Software change requests and bug numbers can be indicated in the code, linking the code with a bug tracking system.
7. Public API code is easier to use by 3rd parties.
8. If you can comment your code then you can demonstrate a greater understanding during code reviews.


Finally, for those of you developing C# or Visual Basic .Net
applications, using Visual Studio 2005, I have created a macro to make
the task of code commenting easier:

1. Download the zip file, containing a VB macro file, from here.
2. Open the macro explorer in Visual Studio 2005.
3. Create a new macros project.
4. Create a new macro in the project and overwrite the VB code (all
macros are written in VB) with the XmlComments.vb code downloaded in
the zip file.
5. Customize VS.Net by adding a keyboard short cut to the “CommentMe” macro in the new project you just created.

So, what does my macro code do that the regular doc comments built into VS.Net (/// in C#) do not already do?

1. Comments are added above classes, methods and properties, depending
on the current cursor position. This makes for faster development, e.g.
when adding comment, just execute the macro when inside the curly
braces. No need for moving the cursor above the method, property or
class to trigger the built-in doc comments.

2. My macro detects parameter types and adds cref tags to the parameter comments.

3. Any exceptions used in a method or property are detected and
automatically commented in the comments above the method or property
using the exception tag.

4. Existing comments are not overwritten by my macro, instead my macro adds missing comment tags to existing comments.

5. When overriding methods and properties from a base class, my macros
code will use the same comment from the base class version.

6. VS.Net adds empty tags when using the built-in doc comments, my macro has a stab at suggesting a default comment.

Question about generics

In my previous post on Generics, I received a comment from Eddie, who
was asking why developers would want to use the following constraint,
in the example below, when he would pass the parameters as IComparable
interface types.

public static bool IsLessThan(T one, T two) where T:IComparable
{
return one.CompareTo(two) < 0;
}

public static bool IsLessThan(IComparable one, IComparable two)
{
return one.CompareTo(two) < 0;
}

The previous comment touches on the generics vs base class debate, of which there is pros and cons to both.

Eddie raises an interesting question, and I am giving it some thought.
A few reasons for not using IComparable as the parameter type come to
mind…

If you wanted to compare value types, casting to IComparable would
convert the value types to a references by boxing, which is what
generics are trying to avoid.

A reference is 4 bytes in length, so, when comparing two short
values,  Eddie’s example would pass at least 8 bytes across the
stack (+ overhead). Using a generic with Unit16 type would only use of
4 bytes for the two parameters.   

Eddie’s example would require up casting the interface reference type to
known type if the method did more than just compare two values with
CompareTo. The whole point of generics is that the developer of a
generic should not have to know anything about the intended type used
in the generic context. Otherwise, we might as well use cast from
System.Object like ArrayList does.

Oops

I forgot to mention in my last post, about Generics, that Sahil Malik helped me out with
the solution. Between the two of us we figured out why parameterized
constructors are not allowed when creating new instances of generic
types.

I would have edited my initial post, but the formatting in my blog that
displays code syntax is not happy when edited a second time in free
text box
(used on the admin page of my blog), and the code gets all
screwed up. I haven’t fixed the link to MSDN magazine in that post for
the same reason.