Logging properties–an easier way
I have often wanted a nice, easy way to simplify the writing and maintenance of code like this:
Log.Trace(string.Format(“FooSetting.BarProperty1 = {0}”), FooSetting.BarProperty1));
Log.Trace(string.Format(“FooSetting.BarProperty2 = {0}”), FooSetting.BarProperty2));
Log.Trace(string.Format(“FooSetting.BazLongerProperty= {0}”), FooSetting.BazLongerProperty));
…for the writing and maintenance of such code is ever filled with tedious mouse clicking, copy and pasting, typo correction in duplicate, manual refactoring of string constants, blah blah ugh.
Turns out that since the introduction of LINQ expressions into C#, there are some major nice-ifications to such code available.
(I’m pretty sure I’m reinventing this, I don’t mind not being the first, just as long I’m helping popularize the practice.)
namespace LogProperty
{
using System.Linq.Expressions;
class Program
{
public int Prop { get; set; }
static void LogProperty<TResult>(Expression<Func<TResult>> expr)
{
Debug.Assert(expr.NodeType == ExpressionType.Lambda);
Debug.Assert(expr.Body.NodeType == ExpressionType.MemberAccess);
string name = ((MemberExpression)expr.Body).Member.Name;
Console.WriteLine(name + " = " + expr.Compile().Invoke());
}
static void Main(string[] args)
{
Program p = new Program();
LogProperty(() => p.Prop);
LogProperty(() => new Program { Prop = 3 }.Prop);
}
}
}
Ta da! Refactorable logging!
Comments
Anonymous
January 05, 2012
The comment has been removedAnonymous
January 06, 2012
using System.Linq.Expressions;Anonymous
December 07, 2012
Note, this blog entry is somewhat obsolete only 2 months after posting, as .NET 4.5 introduced CallerMemberName: msdn.microsoft.com/.../system.runtime.compilerservices.callermembernameattribute.aspxAnonymous
December 07, 2012
@John - cool! Didn't know about that one.