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<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:
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);
}
}