示例#1
0
        public void GenerateWriterMethod(Type type, CodeGenContext ctx, ILGenerator il)
        {
            // arg0: Serializer, arg1: Stream, arg2: value

            var fields = Yardımcılar.GetFieldInfos(type);

            foreach (var field in fields)
            {
                // Note: the user defined value type is not passed as reference. could cause perf problems with big structs

                var fieldType = field.FieldType;

                var data = ctx.GetTypeDataForCall(fieldType);

                if (data.NeedsInstanceParameter)
                {
                    il.Emit(OpCodes.Ldarg_0);
                }

                il.Emit(OpCodes.Ldarg_1);
                if (type.IsValueType)
                {
                    il.Emit(OpCodes.Ldarga_S, 2);
                }
                else
                {
                    il.Emit(OpCodes.Ldarg_2);
                }
                il.Emit(OpCodes.Ldfld, field);

                il.Emit(OpCodes.Call, data.WriterMethodInfo);
            }

            il.Emit(OpCodes.Ret);
        }
示例#2
0
        public void GenerateReaderMethod(Type type, CodeGenContext ctx, ILGenerator il)
        {
            // arg0: Serializer, arg1: stream, arg2: out value

            if (type.IsClass)
            {
                // instantiate empty class
                il.Emit(OpCodes.Ldarg_2);

                var gtfh = typeof(Type).GetMethod("GetTypeFromHandle", BindingFlags.Public | BindingFlags.Static);
                var guo  = typeof(System.Runtime.Serialization.FormatterServices).GetMethod("GetUninitializedObject", BindingFlags.Public | BindingFlags.Static);
                il.Emit(OpCodes.Ldtoken, type);
                il.Emit(OpCodes.Call, gtfh);
                il.Emit(OpCodes.Call, guo);
                il.Emit(OpCodes.Castclass, type);

                il.Emit(OpCodes.Stind_Ref);
            }

            var fields = Yardımcılar.GetFieldInfos(type);

            foreach (var field in fields)
            {
                var fieldType = field.FieldType;

                var data = ctx.GetTypeDataForCall(fieldType);

                if (data.NeedsInstanceParameter)
                {
                    il.Emit(OpCodes.Ldarg_0);
                }

                il.Emit(OpCodes.Ldarg_1);
                il.Emit(OpCodes.Ldarg_2);
                if (type.IsClass)
                {
                    il.Emit(OpCodes.Ldind_Ref);
                }
                il.Emit(OpCodes.Ldflda, field);

                il.Emit(OpCodes.Call, data.ReaderMethodInfo);
            }

            if (typeof(System.Runtime.Serialization.IDeserializationCallback).IsAssignableFrom(type))
            {
                var miOnDeserialization = typeof(System.Runtime.Serialization.IDeserializationCallback).GetMethod("OnDeserialization",
                                                                                                                  BindingFlags.Instance | BindingFlags.Public,
                                                                                                                  null, new[] { typeof(Object) }, null);

                il.Emit(OpCodes.Ldarg_2);
                il.Emit(OpCodes.Ldnull);
                il.Emit(OpCodes.Constrained, type);
                il.Emit(OpCodes.Callvirt, miOnDeserialization);
            }

            il.Emit(OpCodes.Ret);
        }
示例#3
0
        public IEnumerable <Type> GetSubtypes(Type type)
        {
            var fields = Yardımcılar.GetFieldInfos(type);

            foreach (var field in fields)
            {
                yield return(field.FieldType);
            }
        }