Wednesday, July 16, 2008

.NET 3.5 - Extension Methods Magic!

One of my favorite new features about .NET 3.5 is the ability to create Extension Methods. Essentially this provides you with the ability to extend a given type with your own custom methods. Let's think about what you would need to do to retrieve a control value from a ASP.NET FormView. First you need to use the Controls collection or FindControl method to return the control. Then, you need to cast the control to the specific control in question. Finally, you have to cast it to the type you need returned. The following is an example of this:

int woodchucksTotal = Convert.ToInt32(((Label)WoodChuckerForm.FindControl("WoodchucksTotal")).Text);

This syntax is very error prone, tedious, and hard to debug if you are doing it with a large number of controls. Alternatively, and with very little work, you can use extension methods and have syntax like this instead:

int? woodchucksTotal = WoodChuckerForm.ControlToInt32("WoodchucksTotal");

This allows me to simplify my syntax and almost cut it in half and decrease the number of parentheses from 8 to 2. I have also provided means to return a nullable typed integer. This can be helpful if, for example, you'd prefer to insert a null instead of a zero in a database. To be able to implement extension methods, you simply need to use the following two simple steps:

Implement an Extension Method

  1. Create a non-nested static class.
  2. Add static methods that have first parameters use the this modifier with the type being extended.

Sample C# Code

public static class WebControlUtil
{
    public static string ControlToString(this FormView formView, string controlName)
    {
        WebControl ctrl = (WebControl)formView.FindControl(controlName);
        switch (ctrl.GetType().ToString())
        {
            case "System.Web.UI.WebControls.TextBox":
                ctrlText = ((TextBox)ctrl).Text;
                break;
            case "System.Web.UI.WebControls.CheckBox":
                ctrlText = ((CheckBox)ctrl).Checked.ToString();
                break;
            case "System.Web.UI.WebControls.DropDownList":
                ctrlText = ((DropDownList)ctrl).Text;
                break;
        }
        return ctrlText;
    }

    public static bool ControlToBool(this FormView formView, string controlName)
    {
        WebControl ctrl = (WebControl)formView.FindControl(controlName);
        bool ctrlBool = false;
        switch (ctrl.GetType().ToString())
        {
            case "System.Web.UI.WebControls.CheckBox":
                ctrlBool = ((CheckBox)ctrl).Checked;
                break;
        }
        return ctrlBool;
    }

    public static int? ControlToInt32(this FormView formView, string controlName)
    {
        WebControl ctrl = (WebControl)formView.FindControl(controlName);
        int? ctrlInt32 = null;
        switch (ctrl.GetType().ToString())
        {
            case "System.Web.UI.WebControls.TextBox":
                if (((TextBox)ctrl).Text != "")
                {
                    ctrlInt32 = Convert.ToInt32(((TextBox)ctrl).Text);
                }
                break;
            case "System.Web.UI.WebControls.DropDownList":
                ctrlInt32 = Convert.ToInt32(((DropDownList)ctrl).SelectedValue);
                break;
        }
        return ctrlInt32;
    }

    public static DateTime? ControlToDate(this FormView formView, string controlName)
    {
        WebControl ctrl = (WebControl)formView.FindControl(controlName);
        DateTime? ctrlDate = null;
        switch (ctrl.GetType().ToString())
        {
            case "System.Web.UI.WebControls.TextBox":
                if (((TextBox)ctrl).Text != "")
                {
                    ctrlDate = Convert.ToDateTime(((TextBox)ctrl).Text);
                }
                break;
        }
        return ctrlDate;
    }
}

1 comment: