Reputation:
I'm only at chapter 5 in "Essential C#" and not sure if i understand the difference correctly. I tried to make the model below to test one instance of everything in the properties chapter - and it works - but is the example acceptable use of the two ways one can implement properties or are there better ways?
using MarkdownSharp; // StackOverflow's md processor
public class Article
{
public string Headline { get; set; }
public string Content
{
get
{
return _content;
}
set
{
var md = new Markdown();
var html = md.Transform(value);
_content = html;
}
}
private string _content;
public DateTime Published { get; set; } = DateTime.Now;
}
Upvotes: 0
Views: 60
Reputation: 354386
This question may be better suited for codereview.stackexchange, although it's perhaps too tiny a snippet and to vague a question for that.
Personally, I shy away from magic properties that act in surprising ways. It tends to make for APIs that can be hard to use because they are surprising, even if they are somehow “clever” under the hood. You have a property where you set a different value than the one you get out. One thing where this can break would be the +=
operator, which suddenly would work in very weird ways with your Content
property.
I'd probably go with something like
public class Article
{
private string content;
private string renderedContent;
public string Headline { get; set; }
public string Content
{
get { return content; }
set
{
content = value;
renderedContent = null; // reset cached rendered content
}
}
public string RenderedContent
{
get
{
if (renderedContent == null)
{
renderedContent = new Markdown().Transform(content);
}
return renderedContent;
}
}
public DateTime Published { get; set; } = DateTime.Now;
}
As for whether to use field-backed properties, or auto-properties, or computed properties ... that's up to you to decide based on what the property is supposed to do. Auto-properties are fine for simply storing and retrieving a value, e.g. Published
or Headline
here. You need the explicit backing field as soon as you do something more than just reading or writing it in the getter and setter, as shown here in Content
. RenderedContent
could be just a computed property, but I chose to cache the value after initial conversion because you kinda do the same. This pattern here doesn't convert the Markdown until it's actually needed, though.
Upvotes: 1