feanz
9/4/2013 - 9:01 AM

Diff methods to get the typed name of a proeprty

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