How to generate a Simple ToString() implementation with CodeRush templates

A customer recently asked:

Does CodeRush have a quick way to auto-implement ToString()?
If it outputted each prop Name & value it would be great.

Never one to shirk a challenge, I quickly set about finding the quickest way to allow a user to generate a ToString() method which
would provide the requisite information.

The approach I took this time, was that of Templates. Note: This task could certainly have been achieved with a plugin, but it’s
quicker and arguably more efficient to use Templates in this case, so that’s the route I chose to take.

For a generic primer on how to create CodeRush templates see my earlier post: CodeRush Templates - Creation Basics

Structure

The solution to this is to create 3 templates. An Iterating Template, An Item Template and a Delimiting Template

  • The Iterating Template: This is triggered by the user, and controls the iteration of the properties.
  • The Item Template: This represents the text that is emitted for each property encountered.
  • The Separation Template: This is used to determine text that sits between invocations of the item template.

Specifics

The Iterating Template

As indicated this template is the one which is called directly by the user and as such should carry a sensible name. I’m not so great at naming so I chose to call mine ToStringPropertyMethod

It will therefore be invoked whenever the user types ToStringPropertyMethod and hits the spacebar (or tab if you’re in Friction free mode)

The body of this template is:

-------------------------------------------------------------

public override string ToString()
{
return «ForEach(Property,PropertyEach,,PropertySeparator)»;
}

-------------------------------------------------------------

The basic structure of this will look familiar. The signature is that of the standard ToString() override, and the braces are those present in any method in order to denote the start and end of that method.


What will be less familiar is the code within the chevrons (« and »)

This code is a TextCommand which is interpreted by CodeRush, rather than emitted directly into your code.

This TextCommand is called 'ForEach' and it takes up to 5 parameters. In this instance we only need 3 of these.

  • 'Property' specifies that we are interested in iterating through any properties of the current class.
  • 'PropertyEach' is the name of the template to expand for each property found.
  • 'PropertySeparator' is the name of the template to be expanded between any 2 calls to PropertyEach

The other 2 params are unused in this case but control templates expanded at the start and end of the sequence.

As you can see, this template depends on the existance of both PropertyEach and PropertySeperator.

The expansion of the PropertySeperator Template is predictably a simple + sequence thus:

-------------------------------------------------------------

 +

-------------------------------------------------------------


The content of the PropertyEach template is a little more complicated:

-------------------------------------------------------------

"«?Get(itemName)»: " + «?Get(itemName)».ToString()

-------------------------------------------------------------

This represets the building of some code which will itself emit a string representative of the property being iterated.

The bit you may be less familiar with is «?Get(itemName)». It is a StringProvider which provides access to strings setup by previous uses of the «?Set» StringProvider.


In this case, each time the «?ForEach» StringProvider  finds a new Property, it sets itemName to the name of that Property. This gives us a handy way to access that information and emit it into out code.

If you put all of this together and Expand the ToStringPropertyMethod template from within the following class...

-------------------------------------------------------------

    public class Example
    {
        public string PropertyName1 { get; set; }
        public string PropertyName2 { get; set; }
        public string PropertyName3 { get; set; }
    }
-------------------------------------------------------------

...you get the following result...

-------------------------------------------------------------

    public class Example
    {
        public string PropertyName1 { get; set; }
        public string PropertyName2 { get; set; }
        public override string ToString()
        {
            return "PropertyName1: " + PropertyName1.ToString() + "PropertyName2: " + PropertyName2.ToString();
        }

    }
-------------------------------------------------------------


Summary

As you can see, this code will emit the name and value of each property of the class when called.

Obviously the formatting could be improved, but I think you can see the potential demonstrated here.

What about generating XML or JSON based strings.

These, of course, are left as an exercise for the reader. :)





1 comment(s)
Mark Harby

Sweet

Nice one Rory

14 October, 2013

Please login or register to post comments.