As many of you have seen for yourselves, a given project almost always dictates a need for some code that, while useful, exposes some of the more esoteric and bizarre requirements of the project in question. I'm working on such a project right now. One of our bizarre requirements is the need to add an "empty" record at the top of a dataset that was returned from a stored procedure. This is to enable our code to present a combobox a seemingly unselected item (I wuld have done it differently, but that's not what this tip is about). I supposed this is all well and good, and it's done on several pages throughout the web site project. My problem was with the way they're initializing the row. Here's an example:
DataRow row = dataset.Tabels(0).NewRow();
row.ItemArray = new object[]{"", "", 0, "" };
Do you see the problem? Here's a hint - if the schema for the source table changes, this code might break. What happens if a column data type is changed, existing columns are deleted, or if new columns are added? Distaster is what happens, and all of a sudden we're carreening headlong down the Exception Highway.
To resolve the potential issue, I came up with an extension method that solves the problem. Essentially, the method iterates through the row's columns, determines each columns type, and sets a reasonable value to the column. If a default value is specified, that value is used instead. (In our code, a default value is rarely specified - another rookie error.)
So, here's the (extension) method:
public static void Clear(this DataRow row)
{
for (int i = 0; i < row.Table.Columns.Count; i++)
{
DataColumn column = row.Table.Columns[i];
if (column.DefaultValue != null)
{
switch (column.DataType.Name.ToLower().Substring(0,3))
{
case "str": case "cha":
row[i] = "";
break;
case "int": case "uin": case "sho": case "byt":
case "sby": case "dec": case "dou": case "sin":
row[i] = 0;
break;
case "boo":
row[i] = false;
break;
case "dat":
row[i] = new DateTime(0);
break;
case "obj": default :
row[i] = DBNull.Value;
break;
}
}
else
{
row[i] = column.DefaultValue;
}
}
}
I've been paid as a programmer since 1982 with experience in Pascal, and C++ (both self-taught), and began writing Windows programs in 1991 using Visual C++ and MFC. In the 2nd half of 2007, I started writing C# Windows Forms and ASP.Net applications, and have since done WPF, Silverlight, WCF, web services, and Windows services.
My weakest point is that my moments of clarity are too brief to hold a meaningful conversation that requires more than 30 seconds to complete. Thankfully, grunts of agreement are all that is required to conduct most discussions without committing to any particular belief system.