Saturday, May 30, 2009

Enum in Lieu of String Constants

Every now and then, we are faced with situations when using literals seems to be the only way to accomplishing things. Let’s take for example the case of untyped DataSet. One reason why I hated using untyped DataSet is the fact that Intellisense is unable to assist me when accessing the objects of the different collection within it. I'm talking about string indexers which is used to qualify the objects in collection as shown below.

DataTable tblPayers = aDataSet.Tables[“Pharmacy”];
// More codes here
selectedRow[“NCPDPNo”] = “123456”;
There might be typos in my codes already but most probably I’ll find out only during runtime. This situation is even aggravated when you have more than one parts of the codes accessing, let’s say, different columns of a DataTable. In order to be consistent with the indexer qualifier, a good practice is to declare those column names as constants. Ok, ok, some of you might think this is an overkill. Well, it is if you’re dealing with LastName, Birthdate, OrderNo but what if you’re in a totally unfamiliar territory where ClearinghouseSubmitterId, PayerLOB, NCPDPNo and other exotic creatures roam? Trust me, it will pay off sooner or later do it the “overkill” way. So to proceed, you will have something like this snippet:
const string ClearinghouseSubmitterIdColumnName = “ClearinghouseSubmitterId”;
const string PayerLOBColumnName = “PayerLOB”;
const string NcpdpNoColumnName = “NCPDPNo”;
I see nothing wrong with this approach and as a matter of fact, it’s a correct one. But there’s actually shorter and organized one albeit unconventional.

internal enum EnrollmentColumn { EnrollmentId, ClearinghouseSubmitterId, … };
internal enum PayerColumn { NationalPayerNo, PayerLOB, … }
internal enum PharmacyColumn {NCPDPNo, Name, ….}
internal enum Table {Enrollment, Payer, Pharmacy,...};

public class AForm : Form
{
void Foo()
{
DataTable tblPharmacy = aDataSet.Tables[Table.Pharmacy.ToString()];


// Codes to retrieve selected row
selectedPharmacyRow[PharmacyColumn.NCPDPNO.ToString()] = “12345”;
}
}
I know what you’re thinking right now. Enum is not built for this. I agree but as you can see, with the aid of Intellisense, enum becomes a convenient and safe way to code. First of all, it’s shorter to declare enum. You only need to type the name and the ToString() will take care of the rest. One thing to remember though is that the equivalent column or literal should not contain space. So enum is ruled out when you have columns like “Last Name” since space is an invalid token in .NET. Second, the code is a little more organized this time. The name of the enum can be the name of the table. Of course you can also employ other implementation like a static class with a bunch of read-only string get properties but again more coding is involved.