Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

C# Automatic Property Default Value Extension Methods

0.00/5 (No votes)
23 Aug 2011 1  
For .NET 4.0:using System;using System.Collections.Generic;using System.ComponentModel;using System.Reflection;using System.Linq.Expressions;static class AutomaticPropertyExtensions{ private static class Cache where T : class { public static readonly...
For .NET 4.0:

C#
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System.Linq.Expressions;

static class AutomaticPropertyExtensions
{
    private static class Cache<T> where T : class
    {
        public static readonly Action<T> Init;
        public static readonly int PropertyCount;

        static Cache()
        {
            var p = Expression.Parameter(typeof(T), "this");
            var body = Expression.Block(typeof(T)
                .ListPropertiesToReset()
                .Select(pair => Assign(p, pair.Item1, pair.Item2)));

            PropertyCount = body.Expressions.Count;
            if (PropertyCount != 0)
            {
                var result = Expression.Lambda<Action<T>>(body, p);
                Init = result.Compile();
            }
        }
    }
    
    private static Expression Assign(Expression p, PropertyInfo property, object value)
    {
        var prop = Expression.Property(p, property);
        var defaultValue = Expression.Constant(value, property.PropertyType);
        return Expression.Assign(prop, defaultValue);
    }
    
    private static IEnumerable<Tuple<PropertyInfo, object>> ListPropertiesToReset(this Type componentType)
    {
        const BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

        return from PropertyInfo property in componentType.GetProperties(flags)
               where property.CanWrite
               let attributes = property.GetCustomAttributes(typeof(DefaultValueAttribute), true)
               where attributes != null && 0 != attributes.Length
               let attribute = (DefaultValueAttribute)attributes[0]
               let defaultValue = attribute.Value
               where defaultValue != null
               select Tuple.Create(property, defaultValue);
    }

    public static int ResetPropsUsingDefaultAttributes<T>(this T instance) where T : class
    {
        if (instance == null) throw new ArgumentNullException("instance");
        if (Cache<T>.Init != null) Cache<T>.Init(instance);
        return Cache<T>.PropertyCount;
    }
}


Usage:
C#
public class TestClass
{
    [DefaultValue(0.3141)]
    public double MyPie { get; set; }

    [DefaultValue("Pizza")]
    public string MyLove { get; set; }

    public TestClass()
    {
        this.Reset();
    }

    public void Reset()
    {
        this.ResetPropsUsingDefaultAttributes();
    }

    public override string ToString()
    {
        return string.Format("MyPie = {0}, MyLove = {1}",
            MyPie, MyLove == null ? "null" : MyLove);
    }
}

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here