private LocalBuilder ReadValue(Type type, string name, string ns) { LocalBuilder value = ilg.DeclareLocal(type, "valueRead"); LocalBuilder nullableValue = null; int nullables = 0; while (type.IsGenericType && type.GetGenericTypeDefinition() == Globals.TypeOfNullable) { nullables++; type = type.GetGenericArguments()[0]; } PrimitiveDataContract primitiveContract = PrimitiveDataContract.GetPrimitiveDataContract(type); if ((primitiveContract != null && primitiveContract.UnderlyingType != Globals.TypeOfObject) || nullables != 0 || type.IsValueType) { LocalBuilder objectId = ilg.DeclareLocal(Globals.TypeOfString, "objectIdRead"); ilg.Call(contextArg, XmlFormatGeneratorStatics.ReadAttributesMethod, xmlReaderArg); ilg.Call(contextArg, XmlFormatGeneratorStatics.ReadIfNullOrRefMethod, xmlReaderArg, type, DataContract.IsTypeSerializable(type)); ilg.Stloc(objectId); // Deserialize null ilg.If(objectId, Cmp.EqualTo, Globals.NullObjectId); if (nullables != 0) { ilg.LoadAddress(value); ilg.InitObj(value.LocalType); } else if (type.IsValueType) { ThrowValidationException(SR.Format(SR.ValueTypeCannotBeNull, DataContract.GetClrTypeFullName(type))); } else { ilg.Load(null); ilg.Stloc(value); } // Deserialize value // Compare against Globals.NewObjectId, which is set to string.Empty ilg.ElseIfIsEmptyString(objectId); ilg.Call(contextArg, XmlFormatGeneratorStatics.GetObjectIdMethod); ilg.Stloc(objectId); if (type.IsValueType) { ilg.IfNotIsEmptyString(objectId); ThrowValidationException(SR.Format(SR.ValueTypeCannotHaveId, DataContract.GetClrTypeFullName(type))); ilg.EndIf(); } if (nullables != 0) { nullableValue = value; value = ilg.DeclareLocal(type, "innerValueRead"); } if (primitiveContract != null && primitiveContract.UnderlyingType != Globals.TypeOfObject) { ilg.Call(xmlReaderArg, primitiveContract.XmlFormatReaderMethod); ilg.Stloc(value); if (!type.IsValueType) { ilg.Call(contextArg, XmlFormatGeneratorStatics.AddNewObjectMethod, value); } } else { InternalDeserialize(value, type, name, ns); } // Deserialize ref ilg.Else(); if (type.IsValueType) { ThrowValidationException(SR.Format(SR.ValueTypeCannotHaveRef, DataContract.GetClrTypeFullName(type))); } else { ilg.Call(contextArg, XmlFormatGeneratorStatics.GetExistingObjectMethod, objectId, type, name, ns); ilg.ConvertValue(Globals.TypeOfObject, type); ilg.Stloc(value); } ilg.EndIf(); if (nullableValue != null) { ilg.If(objectId, Cmp.NotEqualTo, Globals.NullObjectId); WrapNullableObject(value, nullableValue, nullables); ilg.EndIf(); value = nullableValue; } } else { InternalDeserialize(value, type, name, ns); } return(value); }