Skip to content

Instantly share code, notes, and snippets.

@Sergio0694
Last active September 25, 2019 11:56
Show Gist options
  • Save Sergio0694/827e39f1ffeed8cbb5a43f50a05b5cd2 to your computer and use it in GitHub Desktop.
Save Sergio0694/827e39f1ffeed8cbb5a43f50a05b5cd2 to your computer and use it in GitHub Desktop.
public static Func<object, object> BuildDynamicGetter(ClosureField field)
{
// Create a new dynamic method
FieldInfo[] hierarchy = field.Parents.Append(field.Info).ToArray();
Type ownerType = hierarchy[0].DeclaringType;
DynamicMethod method = new DynamicMethod(
$"Get{field.Info.Name}",
typeof(object), // The return type
new[] { typeof(object) }, // A single object parameter
ownerType); // The type that will own the new method
// Load and cast the argument
ILGenerator il = method.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Castclass, ownerType);
// Unroll the depth traversal until the last parent
foreach (FieldInfo parent in field.Parents)
{
il.Emit(OpCodes.Ldfld, parent);
}
// Get the target field
il.Emit(OpCodes.Ldfld, field.Info);
if (field.FieldType.IsValueType)
{
il.Emit(OpCodes.Box, field.FieldType);
}
il.Emit(OpCodes.Ret);
// Create the proper delegate type for the method
return (Func<object, object>)method.CreateDelegate(typeof(Func<object, object>));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment