public static Action<object, object> CreateSetFieldMethod(FieldInfo fieldInfo)
{
if (fieldInfo.DeclaringType.IsValueType)
{
if (fieldInfo.DeclaringType.StructLayoutAttribute != null)
{
#if DEBUG
throw new FieldAccessException(string.Format("The type '{0}' has a StructLayoutAttribute, and thus cannot have field setter for '{1}' generated. otherwise the .net framework will throw an access exception. As a fix, either create a typeconverter for the type, turn the fields into properties, or remove the structlayout attribute.", fieldInfo.DeclaringType.FullName, fieldInfo.Name));
#else
Console.WriteLine("Using reflection to set field {1}.{0}, due to StructLayoutAttribute being defined. Recommended to define a type converter for the type instead.", fieldInfo.Name, fieldInfo.DeclaringType.Name);
#endif
//fffffff. this has to be done via reflection, otherwise we're gonna get field access exceptions that will crash the program.
return new Action<object, object>((targ, value) => fieldInfo.SetValue(targ, value));
}
}
DynamicMethod dynamicMethod = new DynamicMethod(
String.Concat("_SetF", fieldInfo.Name, "_"),
typeof(void),
new[] { typeof(object), typeof(object) },
fieldInfo.DeclaringType);
ILGenerator generator = dynamicMethod.GetILGenerator();
generator.Emit(OpCodes.Ldarg_0); // push object onto the stack
generator.Emit(OpCodes.Ldarg_1); // push value onto the stack
if (fieldInfo.FieldType.IsValueType)
{
//unbox value to field's type
generator.Emit(OpCodes.Unbox_Any, fieldInfo.FieldType);
}
generator.Emit(OpCodes.Stfld, fieldInfo); // set field value
generator.Emit(OpCodes.Ret); //return
var setter = (Action<object, object>)dynamicMethod.CreateDelegate(typeof(Action<object, object>));
return setter;
}