Diff methods to get the typed name of a proeprty
void Main()
{
var variable = 1;
100000.Times("Get variable name", () => GetName(new {variable}));
100000.Times("Get variable name", () => GetNameCached(new { variable}));
100000.Times("Get variable name", () => GetNameExpression(() => variable));
100000.Times("Get variable name", () => GetNameIL(() => variable));
}
public static string GetName<T>(T item) where T : class
{
var properties = typeof(T).GetProperties();
//Enforce.That(properties.Length == 1);
return properties[0].Name;
}
public static string GetNameExpression<T>(Expression<Func<T>> expr)
{
var body = ((MemberExpression)expr.Body);
return body.Member.Name;
}
public static string GetNameIL<T>(Func<T> expr)
{
// get IL code behind the delegate
var il = expr.Method.GetMethodBody().GetILAsByteArray();
// bytes 2-6 represent the field handle
var fieldHandle = BitConverter.ToInt32(il, 2);
// resolve the handle
var field = expr.Target.GetType()
.Module.ResolveField(fieldHandle);
return field.Name;
}
public static class BenchmarkExtension {
public static void Times(this int times, string description, Action action) {
Stopwatch watch = new Stopwatch();
watch.Start();
for (int i = 0; i < times; i++) {
action();
}
watch.Stop();
Console.WriteLine("{0} ... Total time: {1}ms ({2} iterations)",
description,
watch.ElapsedMilliseconds,
times);
}
}
//possible cache for faster anonymous type declaration lookup
public static class Cache<T>
{
public static readonly string Name;
static Cache()
{
var properties = typeof(T).GetProperties();
Name = properties[0].Name;
}
}
public static string GetNameCached<T>(T item) where T : class
{
return Cache<T>.Name;
}