Action <BasePackable, Type, Stream, object> GetWriteFunc(Type type) { if (WriteFuncs.ContainsKey(type)) { return(WriteFuncs[type]); } foreach (var t in type.GetInterfaces()) { if (PackInterfaces.ContainsKey(t)) { return(PackInterfaces[t]); } } throw new NotSupportedException(); }
public Action <object, Stream> CreateWrite(Type type) { var members = GetMembers(type); var ret = new DynamicMethod("Write_" + type.MetadataToken, null, new Type[] { typeof(object), typeof(Stream) }); var il = ret.GetILGenerator(); foreach (MemberInfo m in members) { var f = m as FieldInfo; var p = m as PropertyInfo; Type mtype = null; if (m is FieldInfo) { mtype = f.FieldType; } else if (m is PropertyInfo) { mtype = p.PropertyType; } if (!WriteFuncs.ContainsKey(mtype)) { throw new NotSupportedException(); } var ifnotnull = il.DefineLabel(); var ifnull = il.DefineLabel(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Castclass, type); if (m is FieldInfo) { il.Emit(OpCodes.Ldfld, f); } else if (m is PropertyInfo) { il.Emit(OpCodes.Call, p.GetGetMethod()); } if (!mtype.IsValueType) { il.Emit(OpCodes.Dup); il.Emit(OpCodes.Brtrue, ifnotnull); il.Emit(OpCodes.Ldc_I4_0); il.Emit(OpCodes.Box, typeof(byte)); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Call, WriteFuncs[typeof(byte)].Method); il.Emit(OpCodes.Pop); il.Emit(OpCodes.Br, ifnull); il.MarkLabel(ifnotnull); il.Emit(OpCodes.Ldc_I4_1); il.Emit(OpCodes.Box, typeof(byte)); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Call, WriteFuncs[typeof(byte)].Method); } if (mtype.IsValueType) { il.Emit(OpCodes.Box, mtype); } il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Call, WriteFuncs[mtype].Method); il.MarkLabel(ifnull); } il.Emit(OpCodes.Ret); return((Action <object, Stream>)ret.CreateDelegate(typeof(Action <object, Stream>))); }