private static Func <object, ObjectClonerReferenceTracker, object> GenerateCloner(Type sourceType) { InternalSerializationStuff.ValidateSupportedTypes(sourceType); ParameterExpression sourceParameter = Expression.Parameter(typeof(object), "sourceParam"); ParameterExpression refTrackerParam = Expression.Parameter(typeof(ObjectClonerReferenceTracker), "refTrackerParam"); var clone = Expression.Parameter(sourceType, "newInstance"); var source = Expression.Parameter(sourceType, "source"); var variables = new List <ParameterExpression>(); var expressions = new List <Expression>(); variables.Add(source); variables.Add(clone); expressions.Add(Expression.Assign(source, Expression.Convert(sourceParameter, sourceType))); if (sourceType.IsPrimitive || sourceType.IsValueType || (sourceType == typeof(string))) { expressions.Add(Expression.Assign(clone, source)); } else if (InternalSerializationStuff.ImplementsISerializableWithSerializationConstructor(sourceType)) { expressions.Add(ISerializableCloner.GenerateISerializableExpression(variables, source, clone, sourceType, refTrackerParam)); } else if (InternalSerializationStuff.ImplementsDictionaryGeneric(sourceType)) { expressions.Add(DictionaryCloner.GenerateDictionaryGenericExpression(variables, source, clone, sourceType, refTrackerParam)); } else if (sourceType == typeof(ExpandoObject)) { expressions.Add(ExpandoCloner.GenerateExpandoObjectExpression(variables, source, clone, refTrackerParam)); } else if (sourceType.IsArray) { expressions.Add(ArrayCloner.GenerateArrayExpression(variables, source, clone, sourceType, refTrackerParam)); } else { expressions.Add(ClassCloner.GenerateClassExpressions(variables, sourceType, source, clone, refTrackerParam)); } // Value types require manual boxing if (sourceType.IsValueType) { expressions.Add(Expression.Convert(clone, typeof(object))); } else { expressions.Add(clone); } return(Expression.Lambda <Func <object, ObjectClonerReferenceTracker, object> >(Expression.Block(variables, expressions), sourceParameter, refTrackerParam).Compile()); }
private static System.Delegate CreateTypeSerializer(Type type) { InternalSerializationStuff.ValidateSupportedTypes(type); var variables = new List <ParameterExpression>(); var expressions = new List <Expression>(); var outputStream = Expression.Parameter(typeof(Stream), "outputStream"); var objToSerialize = Expression.Parameter(type, "objToSerialize"); var objTracking = Expression.Parameter(typeof(SerializerObjectTracker), "objTracking"); var primitiveWriter = GetPrimitiveWriter(type); if (primitiveWriter != null) { Debug.Assert(type.IsPrimitive || type.IsValueType, "Value is not a primitive"); expressions.Add(primitiveWriter(outputStream, objToSerialize, objTracking)); } else if (type == typeof(string)) { expressions.Add(GenerateStringExpression(outputStream, objToSerialize, objTracking)); } else if (InternalSerializationStuff.ImplementsISerializableWithSerializationConstructor(type)) { expressions.Add(ISerializableSerializer.GenerateISerializableExpression(type, variables, outputStream, objToSerialize, objTracking)); } else if (InternalSerializationStuff.ImplementsDictionaryGeneric(type)) { expressions.Add(DictionarySerializer.GenerateDictionaryGenericExpression(type, variables, outputStream, objToSerialize, objTracking)); } else if (type == typeof(ExpandoObject)) { expressions.Add(ExpandoSerializer.GenerateExpandoObjectExpression(type, variables, outputStream, objToSerialize, objTracking)); } else if (type.IsArray) { expressions.Add(GenerateArrayExpression(type, outputStream, objToSerialize, objTracking)); } else { expressions.Add(GenerateClassExpression(type, outputStream, objToSerialize, objTracking)); } var block = Expression.Block(variables, expressions); var a = typeof(Action <, ,>).MakeGenericType(typeof(Stream), type, typeof(SerializerObjectTracker)); return(Expression.Lambda(a, block, outputStream, objToSerialize, objTracking).Compile()); }
private static System.Delegate CreateTypeDeserializer(Type type) { var expressions = new List <Expression>(); var variables = new List <ParameterExpression>(); var inputStream = Expression.Parameter(typeof(Stream), "inputStream"); var objTracker = Expression.Parameter(typeof(DeserializerObjectTracker), "objTracker"); var returnValue = Expression.Parameter(type, "retVal"); variables.Add(returnValue); var primitiveReader = GetPrimitiveReader(type); if (primitiveReader != null) { expressions.Add(Expression.Assign(returnValue, Expression.Convert(primitiveReader(inputStream, objTracker), type))); } else if (type == typeof(string)) { expressions.Add(Expression.Assign(returnValue, GenerateStringExpression(inputStream, objTracker))); } else if (InternalSerializationStuff.ImplementsISerializableWithSerializationConstructor(type)) { expressions.Add(Expression.Assign(returnValue, ISerializableDeserializer.GenerateISerializableExpression(type, variables, inputStream, objTracker))); } else if (InternalSerializationStuff.ImplementsDictionaryGeneric(type)) { expressions.Add(Expression.Assign(returnValue, DictionaryDeserializer.GenerateDictionaryGenericExpression(type, variables, inputStream, objTracker))); } else if (type.IsArray) { expressions.Add(Expression.Assign(returnValue, GenerateArrayExpression(type, inputStream, objTracker))); } else if (type == typeof(ExpandoObject)) { expressions.Add(Expression.Assign(returnValue, ExpandoDeserializer.GenerateExpandoObjectExpression(variables, inputStream, objTracker))); } else { expressions.Add(Expression.Assign(returnValue, GenerateClassExpression(type, inputStream, objTracker))); } expressions.Add(returnValue); var block = Expression.Block(variables, expressions); var f = typeof(Func <, ,>).MakeGenericType(typeof(Stream), typeof(DeserializerObjectTracker), type); return(Expression.Lambda(f, block, inputStream, objTracker).Compile()); }