Last active
September 25, 2019 11:56
-
-
Save Sergio0694/827e39f1ffeed8cbb5a43f50a05b5cd2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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