I stumbled on a feature of C# method resolution that I didn't notice before. Namely, when I explicitly implement an interface that supports a setter, and the implicit interface only offers a protected set, the compiler sensibly defers to the protected set when I call it. So I get most of the convenience of auto-implemented properties, but I can prevent accidental modification of fields by clients who shouldn't be changing them.
As an example,
virtual public DateTime CreatedOn { get; protected set; }
virtual public DateTime? ModifiedOn { get; protected set; }
#region IHaveUpdateDateFields Members
DateTime IHaveUpdateDateFields.CreatedOn
{
get
{
return this.CreatedOn;
}
set
{
this.CreatedOn = value;
}
}
DateTime? IHaveUpdateDateFields.ModifiedOn
{
get
{
return this.ModifiedOn;
}
set
{
this.ModifiedOn = value;
}
}
Then my model binding code doesn't accidentally set the date, but my ORM event listener can check for entities that implement IHaveUpdateDateFields and set the date when persisting my entity.
My questions are:
- Am I relying on defined behavior, or am I guaranteed that all C# compilers will resolve methods this way? I don't want to discover that the C# standard says this kind of method resolution is undefined and then accidentally get a horrifying stack overflow when I build for Mono, for example.
- Is there a nicer (ideally terser) way to do this? I could have a ModelBinder-safe interface that I pass to my controller, but that doesn't seem like it would save me code and I don't think it would provide as transparent an approach of minimizing accidental modification of properties.