/// <summary> /// Generates an expression tree to handle class type serialization /// </summary> /// <param name="outputStream">Stream to write to</param> /// <param name="objTracking">Reference tracker</param> /// <param name="item">Source object</param> /// <param name="itemAsObj">Source object as an object</param> /// <param name="typeExpr">Type of the object as an expression</param> /// <param name="serializer">Serializer temporary variable</param> /// <param name="itemType">Type of the element</param> /// <returns>An expression tree to handle class type serialization</returns> internal static Expression GetWriteClassTypeExpression(ParameterExpression outputStream, ParameterExpression objTracking, Expression item, Expression itemAsObj, ParameterExpression typeExpr, ParameterExpression serializer, Type itemType) { var writeType = Expression.IfThenElse(Expression.Equal(Expression.Call(item, ObjectMih.GetTypeMethod()), Expression.Constant(itemType)), Expression.Block(PrimitiveHelpers.WriteByte(outputStream, Expression.Constant(SerializerObjectTracker.Value0), objTracking), Expression.Assign(typeExpr, Expression.Constant(itemType)), Expression.Assign(itemAsObj, Expression.Convert(item, typeof(object)))), Expression.Block(PrimitiveHelpers.WriteByte(outputStream, Expression.Constant(SerializerObjectTracker.Value1), objTracking), Expression.Assign(itemAsObj, Expression.Call(SerializerMih.PrepareObjectForSerialization(), item)), Expression.Assign(typeExpr, Expression.Call(itemAsObj, ObjectMih.GetTypeMethod())), GenerateStringExpression(outputStream, Expression.Call(SerializedTypeResolverMih.GetShortNameFromType(), typeExpr), objTracking), PrimitiveHelpers.WriteInt32(outputStream, Expression.Call(SerializedTypeResolverMih.GetHashCodeFromType(), typeExpr), objTracking))); return(Expression.IfThenElse(Expression.Equal(item, Expression.Constant(null)), PrimitiveHelpers.WriteByte(outputStream, Expression.Constant(SerializerObjectTracker.Value0), objTracking), Expression.Block(PrimitiveHelpers.WriteByte(outputStream, Expression.Constant(SerializerObjectTracker.Value1), objTracking), writeType, Expression.Assign(serializer, Expression.Call(SerializerMih.GetTypeToObjectSerializer(), typeExpr)), Expression.Invoke(serializer, outputStream, itemAsObj, objTracking)))); }
/// <summary> /// Generate an expression that call the clone implementation method /// </summary> /// <param name="source">Source object</param> /// <param name="refTrackerParam">Reference tracker</param> /// <param name="expectedType">Expected type....mostly used for IQueryable detection</param> /// <returns>An expression that call the clone implementation method</returns> internal static Expression CallCopyExpression(Expression source, ParameterExpression refTrackerParam, Expression expectedType) { var itemAsObject = Expression.Parameter(typeof(object), "itemAsObject"); var variables = new List <ParameterExpression>(); variables.Add(itemAsObject); var expressions = new List <Expression>(); expressions.Add(Expression.Assign(itemAsObject, Expression.Call(SerializerMih.PrepareObjectForSerialization(), source))); expressions.Add(Expression.Assign(itemAsObject, Expression.Call(Expression.Call(ObjectClonerMih.CloneImpl(), Expression.Call(itemAsObject, ObjectMih.GetTypeMethod())), FuncMih.CloneMethodInvoke(), Expression.Convert(itemAsObject, typeof(object)), refTrackerParam))); expressions.Add(Expression.Call(SerializerMih.ConvertObjectToExpectedType(), itemAsObject, expectedType)); return(Expression.Block(variables, expressions)); }
/// <summary> /// Generate an expression tree that handle classes /// </summary> /// <param name="refTrackerParam">Reference tracker</param> /// <param name="source">Source object</param> /// <param name="clone">Clone object</param> /// <param name="sourceType">Type of the source object</param> /// <returns>An expression tree that handle classes</returns> public static Expression GetCloneClassTypeExpression(ParameterExpression refTrackerParam, Expression source, ParameterExpression clone, Type sourceType) { return(Expression.IfThenElse(Expression.Equal(source, Expression.Constant(null)), Expression.Assign(clone, Expression.Constant(null, sourceType)), Expression.Assign(clone, Expression.Convert(CallCopyExpression(source, refTrackerParam, Expression.Call(source, ObjectMih.GetTypeMethod())), sourceType)))); }
private static Func <EnumerableLoopBodyCargo, Expression> CloneKeyValuePair(ParameterExpression clone, ParameterExpression refTrackerParam) { Func <EnumerableLoopBodyCargo, Expression> loopBody = cargo => { var keyExpression = Expression.Property(Expression.Property(cargo.Enumerator, cargo.EnumeratorType.GetTypeInfo().GetDeclaredProperty("Current")), cargo.KvpType.GetTypeInfo().GetDeclaredProperty("Key")); var valueExpression = Expression.Property(Expression.Property(cargo.Enumerator, cargo.EnumeratorType.GetTypeInfo().GetDeclaredProperty("Current")), cargo.KvpType.GetTypeInfo().GetDeclaredProperty("Value")); var addExpr = Expression.Call(clone, DictionaryMih.Add <string, object>(), keyExpression, ClassCloner.CallCopyExpression(valueExpression, refTrackerParam, Expression.Call(valueExpression, ObjectMih.GetTypeMethod()))); var addNullExpr = Expression.Call(clone, DictionaryMih.Add <string, object>(), keyExpression, Expression.Constant(null)); return(Expression.IfThenElse(Expression.NotEqual(valueExpression, Expression.Constant(null)), addExpr, addNullExpr)); }; return(loopBody); }