public static Func <object, T> CreateGetter <T>(FieldInfo field) { DynamicMethod dm = new DynamicMethod(string.Format("Get_{0}.{1}", field.DeclaringType.FullName, field.Name), typeof(T), new Type[] { typeof(object) }, field.DeclaringType, true); ILGenerator il = dm.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); if (field.DeclaringType.IsValueType) { il.Emit(OpCodes.Unbox_Any, field.DeclaringType); } il.Emit(OpCodes.Ldfld, field); if (field.FieldType != typeof(T)) { if (!typeof(T).IsAssignableFrom(field.FieldType)) { TypeCode code = Type.GetTypeCode(typeof(T)); if (code == TypeCode.Boolean) { switch (Type.GetTypeCode(field.FieldType)) { case TypeCode.UInt64: case TypeCode.Int64: il.Emit(OpCodes.Ldc_I4_0); il.Emit(OpCodes.Conv_I8); break; case TypeCode.SByte: case TypeCode.Byte: case TypeCode.Int16: case TypeCode.UInt16: case TypeCode.Int32: case TypeCode.UInt32: il.Emit(OpCodes.Ldc_I4_0); break; default: throw new ArgumentException(); } il.Emit(OpCodes.Ceq); il.Emit(OpCodes.Ldc_I4_0); il.Emit(OpCodes.Ceq); } else { OpCode op = code.ConvertFrom(Type.GetTypeCode(field.FieldType)); if (op == OpCodes.Throw) { throw new ArgumentException(); } if (op != OpCodes.Nop) { il.Emit(op); } } } } il.Emit(OpCodes.Ret); return((Func <object, T>)dm.CreateDelegate(typeof(Func <object, T>))); }
public static Action <object, T> CreateSetter <T>(PropertyInfo property) { MethodInfo method = property.GetSetMethod(true); DynamicMethod dm = new DynamicMethod(string.Format("Set_{0}.{1}", property.DeclaringType.FullName, property.Name), typeof(void), new Type[] { typeof(object), typeof(T) }, property.DeclaringType, true); ILGenerator il = dm.GetILGenerator(); if (!property.DeclaringType.IsValueType) { il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_1); if (property.PropertyType != typeof(T)) { if (!property.PropertyType.IsAssignableFrom(typeof(T))) { TypeCode code = Type.GetTypeCode(property.PropertyType); if (code == TypeCode.Boolean) { switch (Type.GetTypeCode(property.PropertyType)) { case TypeCode.UInt64: case TypeCode.Int64: il.Emit(OpCodes.Ldc_I4_0); il.Emit(OpCodes.Conv_I8); break; case TypeCode.SByte: case TypeCode.Byte: case TypeCode.Int16: case TypeCode.UInt16: case TypeCode.Int32: case TypeCode.UInt32: il.Emit(OpCodes.Ldc_I4_0); break; default: throw new ArgumentException(); } il.Emit(OpCodes.Ceq); il.Emit(OpCodes.Ldc_I4_0); il.Emit(OpCodes.Ceq); } else { OpCode op = code.ConvertFrom(Type.GetTypeCode(typeof(T))); if (op == OpCodes.Throw) { throw new ArgumentException(); } if (op != OpCodes.Nop) { il.Emit(op); } } } } il.Emit(OpCodes.Call, method); } il.Emit(OpCodes.Ret); return((Action <object, T>)dm.CreateDelegate(typeof(Action <object, T>))); }