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. :)
Free DevExpress Products - Get Your Copy Today
The following free DevExpress product offers remain available. Should you have any questions about the free offers below, please submit a ticket via the
DevExpress Support Center at your convenience. We'll be happy to follow-up.