Setting non-public property with type safety (no more strings)
Sometimes I have a property where the get-part is public and the set-part is private or protected. Like this:
public class Forum
{
public virtual int TopicCount { get; protected set; }
// More code...
}
There can be various reasons for this design. For me it is often when I make database optimizations where I don’t want to be able to change a property directly in the code, but instead do it directly against the database.
Still, sometimes I want to set the value in unit tests. How do I do that?
Before C# 3.0 I had to rely on having a string with the property name and then use reflection. The main disadvantage with this approach is that if you rename the property you have to make sure that the string is also changed, which is time-consuming and error-prone.
So, with C# 3.0 you no longer need that string. You could use the new Expression-tree feature like this instead:
protected static void SetProperty<TObj, TValue>(TObj obj,
Expression<Func<TObj, TValue>> property, TValue value)
{
var propertyInfo = (PropertyInfo)((MemberExpression)property.Body).Member;
propertyInfo.SetValue(obj, value, null);
}
I have placed this method in my BaseTest class, since I only use it in my tests. Now you can write code like this to set the property:
var forum = new Forum();
SetProperty(forum, f => f.TopicCount, 2);
This is only a scratch on the surface of what you can accomplish with Expression-trees.