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!

image