Friday, June 17, 2011

Effective usage of the value parameter in setters: an example with WebHeaderCollection

A couple of days ago I had to implement a read/write property that would store a WebHeaderCollection associated with a web response. My first take on that was to create an automatic property that would handle getting and setting the values. So far, so good.
Yet, when I tried to assign the value wrapped by that property to a Header collection associated with a Request object, the application threw an exception. After googling awhile I found out that ASP.NET prevents the code from setting some HTTP headers for the request. So, if I were to set the property appropriately, only “eligible” headers would be copied from the response. I decided to stash the filtering in the setter:

private static WebHeaderCollection _WikiHeaders;
public static WebHeaderCollection WikiHeaders
{
  get
  {
    return _WikiHeaders;
  }
  set
  {
    if (null != value as WebHeaderCollection)
    {
      _WikiHeaders.Clear();
      // the value parameter is implicitly typed as WebHeaderCollection
      foreach (string webHeader in value.Keys)
      {
        // check if the current header can be set for the request
        if (!WebHeaderCollection.IsRestricted(webHeader))
            _WikiHeaders.Add(webHeader, value[webHeader]);
      }
    }
  }
}

To my mind, there are two important points about the property described above:
  1. The value parameter is implicitly typed as the property itself – the JIT compiler enforces that. So, you can safely assume that if the property is of the WebHeaderCollection type, then the value parameter is of the same type, too. By implication, you can treat the value parameter as a variable of the respective type (call its methods, get or set properties, etc.)
  2. The WebHeaderCollection.IsRestricted() static method is useful for testing if an HTTP header can be set for the request. It saves programmers from having to author such a checker from scratch and helps them focus on business logic.
BTW, the property I was talking about in this post could be used like below:
Response.Headers = WikiHeaders;

No comments: