Web Development & Execution
David Addison
by David Addison
share this
?fl
« Back to the Blog

Rendering ASP.NET control objects using generics

12/27/2010
Rendering ASP.NET control objects using generics

This is just a quick how-to post on generics and rendering controls in C# .NET. In the System.Web.UI namespace there is the control class-where most asp controls inherit from. An example is asp:Textbox or asp:Panel. Lets say that you are writing a custom server control, or you want to programmatically modify the rendered contents of an asp:Panel. The rendered contents will contain the HTML outputted by all asp controls in the panel, plus the text contents. Basically, it contains the output that is sent to the browser.

Every class that inherits from the control class will have a method named RenderControl(), this is the method that will generate the HTML for the specific control. Here is some basic code that will render a Panel:

public static string RenderPanel(Panel p)
{
// get the text for the control
using (StringWriter sw = new StringWriter())
using (HtmlTextWriter htw = new HtmlTextWriter(sw))
{
p.RenderControl(htw);
return sw.ToString();
}
}

This is nothing too fancy. You could even write this inline without setting it up as a method. Note the 'using' statements, we can use them because StringWriter and HtmlTextWriter both implement the IDisposable interface which means that the system will automatically perform garbage collection. Without the 'using' statements you would have to call sw.Dispose() and htw.Dispose() respectively. Note that sw is passed as an argument to the new HtmlTextWriter during instantiation. This is why we pass htw to the RenderControl method of the Panel, but return sw.ToString().

The above method is great but there are so many controls, why would we want to write this method over and over for each different type? We don't have to thanks to Generics. Generics in C# is a way of creating code that does not know directly what type will be passed. There are many caveats to using Generics. This is only an introduction. Generics evolved from C++ templating which is very similar in usage and syntax. The basic syntax for creating a Generic method is: public void MethodName (T genericObject1); Note the use of 'T' to represent the unknown type.

Here is what our RenderControl() method looks like as a Generic method:

private static string RenderControl (T c) where T : Control, new()
{
// get the text for the control
using (StringWriter sw = new StringWriter())
using (HtmlTextWriter htw = new HtmlTextWriter(sw))
{
c.RenderControl(htw);
return sw.ToString();
}
}

Note where we filled in the types with 'T'. Also the part: 'where T : Control, new()" is a type constraint that says T has to inherit from the Control class, and has to implement the 'new' keyword which means that the type cannot be static or abstract. By utilizing Generics we can use the same code for infinite number of controls that inherit from the Control class. This means we only have to write the code once, and that we will not have to update possibly hundreds of duplicate methods (each for a different type) if we ever have to update this code.

Here are two examples of how you would call this method:

// Explicit type
Panel p = new Panel();
string s = RenderControl (p);

// Implicit type
Panel p = new Panel();
string s = RenderControl(p);

The first method explicitly provides the type as whereas the second method implicitly infers what the type is based on the type of the argument provided. This is because we can assume that is the same type as (T obj) in the method signature RenderControl (T obj);

Here are few more interesting examples of Generic Syntax:

public void MethodName (T genericObject1, U genericObject2); - Declaring multi type generic method. T and U are two types respectively. public T MethodName (T genericObject1); - This method returns a type of T.

Generics also have some interesting characteristics. They can improve your application's performance by limiting the number of casts and boxing operations that occur. Also they provide compile time errors instead of run time. This means that your application is more likely to run with fewer errors. And of course Generics means you can write fewer lines of code that are more powerful than the alternative.

To read more about Generics visit MSDN.

Thanks!

Thank you for contacting us!

We'll be in touch!

Back Home ×