I have a C# class that represents a content type in a web content management system.
We have a field that allows a web content editor to enter an HTML template for how the object is displayed. It basically uses the handlebars syntax for substituting object property values into the HTML string:
<h1>{{Title}}</h1><p>{{Message}}</p>
From a class design perspective, should I expose the formatted HTML string (with substitution) as a property or method?
Example as property:
public class Example
{
private string _template;
public string Title { get; set; }
public string Message { get; set; }
public string Html
{
get
{
return this.ToHtml();
}
protected set { }
}
public Example(Content content)
{
this.Title = content.GetValue("title") as string;
this.Message = content.GetValue("message") as string;
_template = content.GetValue("template") as string;
}
private string ToHtml()
{
// Perform substitution and return formatted string.
}
}
Example as method:
public class Example
{
private string _template;
public string Title { get; set; }
public string Message { get; set; }
public Example(Content content)
{
this.Title = content.GetValue("title") as string;
this.Message = content.GetValue("message") as string;
_template = content.GetValue("template") as string;
}
public string ToHtml()
{
// Perform substitution and return formatted string.
}
}
I'm not sure from a design standpoint does it make a difference or are there reasons why one approach is better than the other?
Best Answer
UPDATE: This question was the subject of my blog in May 2014. Thanks for the great question!
To add to Robert Harvey's answer: a property should be:
logically a property of the class, the way that say its color or year or model are the properties of a car.
not more than, let's say, ten times slower to compute than fetching from a field.
something you don't mind being computed while debugging. The VS debugger automatically computes properties.
unable to fail. Getters should always return a value no matter what the state of the object is.
I don't think your proposed
Html
property hits any of those. Don't make it a property unless it hits all of them.