Generic Methods… Now there’s a thing

Like the rest of the .NET world I have been soaking up the classes in the System.Collections.Generic namespace which have saved me a shed load of lines of custom collection code.

The other day I was writing some CodeSmith templates and needed a class to represent a property that could be hydrated from an XmlNode. And thus I began…

private XmlNode _propNode; 

public string Name 

{ 

    get 

    { 

        string attName = "name"; 

        //check the attribute exists 

        if (_propNode.Attributes[attName] != null) 

            //it does so return it 

            return _propNode.Attributes[attName].Value; 

        //it doesn't so return an empty string 

        return string.Empty; 

    } 

}

After the first few properties I realised I needed to refactor the XmlNode reading out as I was going to have about 20 properties that did the same thing. The problem was that the Value property of the Attribute returns a string so I was going to have to do some type conversion and so would need a method for each type string, int and bool that I needed. I seemed to recall reading about Generic methods and so I investigated… As it turns out I ended up wrapping this method with a method for each type anyway but I discovered Generic methods along the way which I’d not taken advantage of before.

public void GetAttributeValue<T>(ref T attValue, 

    XmlNode nodeToParse, string attName) 

{ 

    //check the attribute exists 

    if(nodeToParse.Attributes[attName] != null) 

    { 

        //get the string value 

        string strVal = nodeToParse.Attributes[attName].Value; 

        //set the attributeValue that has  

        //been passed in by reference, casting it 

        //from an object using the Generic parameter 

        //and using its own type to perform the conversion 

        attValue = (T)Convert.ChangeType(strVal, 

            typeof(attValue)); 

        attValue = (T)Convert.ChangeType(strVal, 

            typeof(T)); 

    } 

}

You can’t specify a Generic return type so you get the value out by passing in an argument by reference. So, you call this method like so:

public bool IsPrimaryKey 

{ 

    get 

    { 

        //set your default value here 

        //that is returned if the attribute 

        //doesn't exist 

        bool returnVal = false; 

        //call the method specifying the type 

        GetAttributeValue<bool>(ref returnVal, 

            _propNode, "isPrimaryKey"); 

        return returnVal; 

    } 

}

This allowed me to use the same method for all of the types of parameter I wanted to fill from the XmlNode’s attributes.

In the end this didn’t save me a great deal of code from doing it without using Generics and I still ended up casting the return value from an object so there would be no performance benefit either (not that performance was an issue here) but it is definitely an interesting language feature that I am sure I will find more uses for…

Advertisements

3 Responses to “Generic Methods… Now there’s a thing”


  1. 1 JCollum July 25, 2007 at 1:32 am

    Little issue:

    This line:
    attValue = (T)Convert.ChangeType(strVal, typeof(attValue));

    Should be this:
    attValue = (T)Convert.ChangeType(strVal, typeof(T));

  2. 2 Graham Pengelly July 25, 2007 at 10:00 am

    Oh aye… Well spotted 🙂

    When I look back at the working code I have actually gone for:

    attValue = (T)Convert.ChangeType(strVal, attValue.GetType());

    but yours definitely trumps that for aesthetics. (note to self: ease up on the Ruby)

  3. 3 Results Provillus August 25, 2013 at 1:12 am

    After I initially commented I appear to have clicked on the -Notify me when new comments are added- checkbox and now whenever a comment is added I recieve 4 emails with the
    same comment. There has to be a means you are able to remove me from that service?
    Cheers!


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s





%d bloggers like this: