public override void GenerateDeserializeIL(MethodGenerator g) { SetMember(g, () => { var count = g.Declare <int>(); g.Assign(count, () => { SerializationMethodHelper.ReadLength(g, this.DTOMemberName);//读取数量 }); var list = g.Declare(this.TargetType); g.If(() => { g.Load(count); g.Load(0); return(LogicOperator.LessThan); }, () => { //数量小于1 //list = new List<T>(); var elementType = this.TargetType.ResolveElementType(); g.Assign(list, () => { g.NewObject(this.TargetType); }); }, () => { //list = new List<T>(); g.Assign(list, () => { g.NewObject(this.TargetType); }); var elementType = this.TargetType.ResolveElementType(); g.For(count, (index) => { var item = g.Declare(elementType); g.Assign(item, () => { SerializationMethodHelper.ReadElement(g, this.DTOMemberName, elementType, index); }); g.Load(list); g.Load(item); g.Call(this.TargetType.ResolveMethod("Add", elementType)); }); }); g.Load(list); }); }
public void GenerateFill(ICilWriter msilWriter) { var g = new MethodGenerator(msilWriter); var instance = g.GetParameter(0); g.If(() => { g.Load(instance); return(BinaryOperator.IsNull); }); { if (_def.Type.IsAbstract) { g.BeginCall(typeof(BarfErrors).ResolveMethod("RaiseAbstractConstructionError", typeof(Type))); g.Load(_def.Type); g.EndCall(); } else { g.BeginAssign(instance); { g.NewObject(_def.Type); } g.EndAssign(); } } g.EndIf(); foreach (var part in _def.Parts) { g.BeginScope(); { var member = g.CreateExpression(instance); if (part.Member == null) { member.MakeReadOnly(); } else { member.AddMember(part.Member); } var context = new GenFillContext(g, member, part); var builder = PartResolver.Current.GetPartBuilder(part.Type, part, true); builder.GenerateFillPart(context); } g.EndScope(); } g.Return(); }
/// <summary> /// Generates the body of the <see cref="BarfSerializer{T}.CreateEmpty()"/>. /// </summary> /// <param name="msilWriter">The MSIL writer to write to.</param> public void GenerateCreateEmptyMethod(ICilWriter msilWriter) { var g = new MethodGenerator(msilWriter); if (_def.Type.IsValueType) { g.LoadDefaultOf(_def.Type); } else { g.NewObject(_def.Type, Type.EmptyTypes); } g.Return(); }
private static CreateInstanceMethod GenerateCreateInstanceMethod(ConstructorInfo constructor) { var objectType = constructor.DeclaringType; DynamicMethod method = new DynamicMethod(string.Format("CreateInstanceByConstructor_{0}", Guid.NewGuid().ToString("n")) , typeof(object) , new Type[] { typeof(object[]) } , true); MethodGenerator g = new MethodGenerator(method); //以下代码把数组参数转成,new T(arg0,arg1)的形式 var result = g.Declare(objectType, "result"); var objs = g.Declare <object[]>(); g.Assign(objs, () => { g.LoadParameter(0); }); g.Assign(result, () => { g.NewObject(constructor, () => { var index = g.Declare <int>(); var prms = constructor.GetParameters(); for (var i = 0; i < prms.Length; i++) { g.Assign(index, () => { g.Load(i); }); g.LoadElement(objs, index); g.Cast(prms[i].ParameterType); } }); }); g.LoadVariable("result"); g.Cast(typeof(object)); g.Return(); var invoke = method.CreateDelegate(typeof(Func <object[], object>)); return(new CreateInstanceMethod(invoke)); }
private static CreateInstanceMethod GenerateCreateInstanceMethod(Type objectType) { DynamicMethod method = new DynamicMethod(string.Format("CreateInstance_{0}", Guid.NewGuid().ToString("n")) , typeof(object) , Array.Empty <Type>() , true); MethodGenerator g = new MethodGenerator(method); var result = g.Declare <object>("result"); g.Assign(result, () => { g.NewObject(objectType); g.Cast(typeof(object)); }); g.LoadVariable("result"); g.Return(); var invoke = method.CreateDelegate(typeof(Func <object>)); return(new CreateInstanceMethod(invoke)); }
public void GenerateInnerDeserializeMethod(ICilWriter msilWriter) { var g = new MethodGenerator(msilWriter); var instance = g.CreateExpression(g.GetParameter(0)); var args = g.CreateExpression(g.GetParameter(1)); var header = g.DeclareLocal(typeof(BarfObjectHeader)); g.BeginAssign(header); { g.Load(args); g.Call(typeof(BarfDeserializationArgs) .ResolveMethod("BeginObject") .MakeGenericMethod(_def.Type)); } g.EndAssign(); var version = g.CreateExpression(header).AddMember("Version"); g.If(() => { g.Load(header); g.LoadMember("IsNull"); return(BinaryOperator.IsTrue); }); { g.BeginAssign(instance); g.LoadNull(); g.EndAssign(); } g.Else(); { g.If(() => { g.Load(instance); return(BinaryOperator.IsNull); }); { if (_def.Type.IsAbstract) { g.BeginCall(typeof(BarfErrors).ResolveMethod("RaiseAbstractConstructionError", typeof(Type))); g.Load(_def.Type); g.EndCall(); } else { g.BeginAssign(instance); g.NewObject(instance.Type); g.EndAssign(); } } g.EndIf(); var partsByVersion = _def.Parts .GroupBy <PartDefinition, int>(part => part.Version) .OrderBy <IGrouping <int, PartDefinition>, int>(group => group.Key); int count = 0; foreach (var versionGroup in partsByVersion) { g.If(() => { g.Load(version); g.Load(versionGroup.Key); return(BinaryOperator.GreaterThanOrEqualTo); }); { foreach (var part in versionGroup) { Trace.WriteLine("\tBuilding Deserialize Part - " + part.FullName); g.BeginScope(); var context = new GenDeserializeContext(g, part, instance, args, header); part.GetCurrentBuilder() .GenerateDeserializePart(context); g.EndScope(); } } count++; } for (; count > 0; --count) { g.EndIf(); } if (_def.IsForwardCompatible) { g.If(() => { g.Load(header).LoadMember("Version"); g.Load(_def.CurrentVersion); return(BinaryOperator.GreaterThan); }); { g.Load(args); g.BeginCall(typeof(BarfDeserializationArgs) .ResolveMethod( "CaptureFutureData", new[] { _def.Type }, typeof(BarfObjectHeader), new GenericParameter(0).MakeByRefType())); { g.Load(header); g.Load(instance, LoadOptions.AnyAsAddress); } g.EndCall(); } g.EndIf(); } } g.EndIf(); g.Load(args).BeginCall(typeof(BarfDeserializationArgs) .ResolveMethod("EndObject", new[] { _def.Type }, typeof(BarfObjectHeader))); { g.Load(header); } g.EndCall(); g.Return(); }