public TSource ConvertFromData <TSource>(object data, ConvertFromDataFlags flags = ConvertFromDataFlags.Default) { TSource result = default(TSource); ConvertFromData(data, ref result, flags); return(result); }
public void ConvertFromData <TSource>(object data, ref TSource source, ConvertFromDataFlags flags = ConvertFromDataFlags.Default) { // Special case: null if (data == null) { source = default(TSource); return; } var dataType = data.GetType(); var dataIsValueType = dataType.GetTypeInfo().IsValueType; var dataConverter = GetDataConverter(dataType, typeof(TSource), ConversionType.DataToObject); if (dataConverter == null) { // Special case: no conversion required if (data is TSource) { source = (TSource)data; return; } throw new InvalidOperationException(string.Format("Could not find a valid converter from type {0} to {1}", dataType, typeof(TSource))); } object sourceObject; bool alreadyStoredInConvertedObjects = ((flags & ConvertFromDataFlags.Construct) == 0); if (!dataIsValueType && dataConverter.CacheResult && ((flags & ConvertFromDataFlags.Construct) != 0)) { // Check cache object cachedSource; if (convertedObjects.TryGetValue(new ConvertedObjectKey(data, dataConverter.ObjectType), out cachedSource)) { source = (TSource)cachedSource; return; } sourceObject = source; if (dataConverter.CanConstruct) { dataConverter.ConstructFromData(this, data, ref sourceObject); // Register information so that if RegisterCurrentObject is called, it will be stored in convertedObjects if (sourceObject != null) { convertedObjects.Add(new ConvertedObjectKey(data, dataConverter.ObjectType), sourceObject); alreadyStoredInConvertedObjects = true; } } } else { sourceObject = source; } if (((flags & ConvertFromDataFlags.Convert) != 0)) { dataConverter.ConvertFromData(this, data, ref sourceObject); if (!dataIsValueType && dataConverter.CacheResult) { // If not stored manually through RegisterCurrentObject, register our object now // Note: we can'ty reuse objectKey as it might have been reentrant if (!alreadyStoredInConvertedObjects) { convertedObjects.Add(new ConvertedObjectKey(data, dataConverter.ObjectType), sourceObject); } } } source = (TSource)sourceObject; }