Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Property Access Test
using System;
using System.Diagnostics;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
namespace PropertyAccessTest
internal static class Program
private static void Benchmark(object obj, PropertyInfo prop, Func<object, object> accessor, string name)
var stopWatch = Stopwatch.StartNew();
for (var i = 0; i < 10000000; i++)
var result = accessor(obj);
Console.WriteLine($"{name}: {stopWatch.ElapsedMilliseconds}ms.");
private static Func<object, object> ByReflection(PropertyInfo prop)
=> o => prop.GetGetMethod().Invoke(o, new object[] { });
private static Func<object, object> ByCompile(PropertyInfo prop)
var param = Expression.Parameter(typeof(object));
var exp = Expression.Lambda<Func<object, object>>(
Expression.Convert(param, prop.DeclaringType),
return exp.Compile();
private static Func<object, object> Converter<I, O>(Delegate func)
=> o => ((Func<I, O>)func)((I)o);
private static Func<object, object> ByCreateDelegate(PropertyInfo prop)
var converter = typeof(Program)
.GetMethod(nameof(Converter), BindingFlags.Static | BindingFlags.NonPublic)
.MakeGenericMethod(prop.DeclaringType, prop.PropertyType)
.CreateDelegate<Func<Delegate, Func<object, object>>>();
var accessor = prop
.CreateDelegate(typeof(Func<,>).MakeGenericType(prop.DeclaringType, prop.PropertyType));
return converter(accessor);
private static Func<object, object> ByEmit(PropertyInfo prop)
var method = new DynamicMethod("GetProperty", typeof(object), new[] { typeof(object) });
var il = method.GetILGenerator();
var get = prop.GetGetMethod();
il.Emit(get.IsVirtual ? OpCodes.Callvirt : OpCodes.Call, get);
return method.CreateDelegate<Func<object, object>>();
private record Testee(int Value);
internal static void Main(string[] args)
var testee = new Testee(1);
var prop = typeof(Testee).GetProperty(nameof(Testee.Value));
Benchmark(testee, prop, ByReflection(prop), "By Reflection");
Benchmark(testee, prop, ByCompile(prop), "By Compile");
Benchmark(testee, prop, ByCreateDelegate(prop), "By CreateDelegate");
Benchmark(testee, prop, ByEmit(prop), "By Emit");
<Project Sdk="Microsoft.NET.Sdk">
<PackageReference Include="System.Reflection.Emit.Lightweight" Version="4.7.0" />
$ dotnet run -c Release
By Reflection: 993ms.
By Compile: 40ms.
By CreateDelegate: 148ms.
By Emit: 23ms.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment